我们什么时候需要使用Python的导入语句?

5

有一段代码我不明白为什么能够工作。从我的理解来看,它不应该起作用。问题可以如下简单说明:

"Main.py"

from x import * #class x is defined
from y import * #class y is defined


xTypeObj = x()
yTypeObj = y()
yTypeObj.func(xTypeObj)

"x.py"

class x(object):

    def __init__...
        ...
    def functionThatReturnsAString(self):
        return "blah"

"y.py"

#NO IMPORT STATEMENT NEEDED?? WHY

class y(object):
    def __init__...
        ...
    def func(self, objOfTypeX):
        print(objOfTypeX.functionThatReturnsAString())

我的问题是,为什么在“y.py”中我不需要像这样的导入语句:import x,请问原因是什么?涉及到IT技术相关内容。
from x import functionThatReturnAString()

它如何确定调用此方法?

你谈论类并调用一些方法,但是你的模块只定义函数,而不是类和方法... #困惑 - heltonbiker
4
你非常想学习Python教程,特别是关于类的部分。以下是链接:http://docs.python.org/2/tutorial/ 和 http://docs.python.org/2/tutorial/classes.html 。 - Martijn Pieters
你将它作为参数传递了进去。 - Keith
3
@FredLarson:这在这里不会有任何影响。你认为会发生什么? - Martijn Pieters
2
@MartijnPieters:只是一个想法。现在我仔细看了一下,我认为你是正确的。 - Fred Larson
3个回答

9

Python是一种面向对象的编程语言。在这种语言中,值是对象,而对象可以有方法。

functionThatReturnsAString函数是一个类上的方法,objOfTypeX是该类的实例。类的实例携带着它的所有方法。

这就是为什么在Python中,例如list对象有一个.append()方法的原因:

>>> alist = []
>>> alist.append(1)
>>> alist
[1]
list类有一个.append()方法,您不需要导入该方法即可调用它。您只需要引用一个列表实例即可。
从技术上讲,Python中的list是一种类型,但在这里这个区别并不重要。总的来说,为了讨论的目的,类型和类是相同的东西。
请阅读Python教程,其中在后面的章节中解释了类(但您可能需要先浏览前几章)。

你的回答让我感觉好像我比实际更无知。问题不在于"面向对象",我知道类的实例是什么......我来自C++世界。问题来自"动态类型与静态类型"。在C++中,在y.py文件中,你需要包含一个头文件,给出objOfTypeX.functionThatReturnsAString()的签名,否则在编译时会报错"objOfTypeX没有名为...的方法"。在Python中,我猜它会在运行时查找这个方法是否存在,如果不存在,则抛出错误。你的回答没有涉及到这个问题,所以我接受了另一个回答。 - Tommy
也就是说,我不确定为什么 funct() 不需要知道方法 functionThatReturnsAString() 的存在,而在 C++ 中,您必须通过告诉 y.py 来“证明”该函数确实存在。我不知道 Python 不需要这样的证明,它只会在运行时报错,说“这个函数不存在,就像你说的那样”。 - Tommy
@Tommy:说句公道话,这完全没有从你的问题中表现出来。一些表明你期望事情如何工作的迹象将有助于更清楚地表达。 - Martijn Pieters
@Tommy:还有要明确的是:很高兴你找到了一个帮助你的答案!这就是SO的全部意义,向Josh Heitzman致敬,他意识到了你的问题所在。 :-) - Martijn Pieters
我的注释 "#NO IMPORT STATEMENT NEEDED?? WHY" 和 "from x import functionThatReturnAString()" 的目的是表明我为什么不需要像在其他面向对象语言(如C++/Java)中那样告诉y.py关于这个函数的存在而感到困惑。 - Tommy
@Tommy:但只有那些在Java和/或C++方面拥有足够经验并熟悉可能存在的混淆的人才能猜测出来。 - Martijn Pieters

3

Python是一种动态类型语言。与静态类型语言(如C++和Java)不同,方法的调用直到实际执行时才会绑定,因此导入定义该方法的模块不是必需的。这有几个含义:

  1. 在运行时可以向实例中添加和删除方法(和数据成员),因此,即使两个Foo类的实例属于相同的类型,它们也可能具有不同的方法。
  2. 在运行时可以向类中添加和删除方法(以及数据成员),这将影响所有当前实例以及新实例。
  3. 可以在运行时添加和删除基类到一个类中。

请注意,这不是动态类型语言和静态类型语言之间所有差异的详尽列表。


与C++和Java等静态类型语言不同,方法的调用直到实际执行时才绑定,因此导入定义该方法的模块并不是必需的。--- 这正是我正在寻找的答案。谢谢! - Tommy

1

函数yTypeObj.func从导入该类的main.py中调用。因此,对象可以被构造并传递到函数中,其中包括其所有方法(functionThatReturnAStringobjOfTypeX的一个方法)。


所以我不太明白何时需要导入(import)。不是在调用另一个类的方法的任何类中,因为y调用了x的函数。 - Tommy
当您想要定义一个新对象时,需要导入类(或任何其他属性)。否则,您将没有构造新对象的配方。您可以将对象传递给任何您喜欢的函数(该函数不必知道这样一个类的存在)。 - btel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接