Python import 语句是否也自动导入依赖项?
Does Python import statement also import dependencies automatically?
我有以下文件app.py
class Baz():
def __init__(self, num):
self.a = num
print self.a
def foo(num):
obj = Baz(num)
和第二个文件main.py
from app import foo
foo(10)
运行 文件 python main.py
给出了正确的输出。
现在在第二个文件中,我只是导入函数而不是 class,尽管我的函数的成功执行也需要 class。
导入函数时 Python 会自动导入 运行 该函数所需的所有其他内容,还是会自动在当前目录中搜索 class?
Python 不会自动执行任何这些操作。
当您从模块(在本例中为 app
模块)导入某些内容时,Python 首先 运行 相应文件中的所有代码(app.py
).您编写的文件 app.py
中的代码做了两件事:
- 定义 class
Baz
- 定义函数
foo
当函数 foo
运行s 时,Python 在 foo
所属的模块中查找 Baz
,并且仅在该模块中查找。 (好吧,它还检查函数 foo
中定义的局部变量,但除了 obj
之外你没有任何局部变量。)具体来说,它会查找 app.Baz
。如果您更改 main.py
以执行相同的搜索:
from app import foo
foo(10)
import app # same app that was already imported
print app.Baz
你会看到app.Baz
就是你在app.py
中定义的class。
如果您将 class Baz
的定义放在另一个文件中,并且如果您不导入该文件,Python 将不会 运行 它。这表明 Python 不会 自动导入依赖项。特别是,假设 app.py
包含
def foo(num):
obj = Baz(num)
并且baz.py
包含
class Baz():
def __init__(self, num):
self.a = num
print self.a
和main.py
不变。你会得到一个错误,因为 Python 没有 运行 定义 class Baz
.
的代码
正如@DavidZ 已经提到的,整个 Python 文件在我们导入时被编译。但是当解析函数体时会发生另一件特殊的事情,函数知道它应该在局部范围内寻找哪些变量以及它应该在全局范围内寻找哪些变量(当然也有自由变量)。
>>> import dis
>>> dis.dis(foo)
7 0 LOAD_GLOBAL 0 (Baz)
3 LOAD_FAST 0 (num)
6 CALL_FUNCTION 1
9 STORE_FAST 1 (obj)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
所以,这里 Baz
必须从全局范围获取。
But how to identify this global scope when we import app.py in another
file?
好吧,每个函数都有一个附加的特殊属性 __globals__
,其中包含其实际的全局命名空间。因此,这就是 Baz
:
的来源
>>> foo.__globals__['Baz']
<class __main__.Baz at 0x10f6e1c80>
因此,应用程序的模块字典和 foo.__globals__
指向同一个对象:
>>>sys.modules['app'].__dict__ is foo.__globals__
True
因此,即使您在导入 foo
后在 main.py
中定义另一个名为 Baz
的变量,它仍然会访问实际的 Baz
.
来自 data-model page:
__globals__ func_globals
:
A reference to the dictionary that holds the function’s global
variables — the global namespace of the module in which the function
was defined.
我有以下文件app.py
class Baz():
def __init__(self, num):
self.a = num
print self.a
def foo(num):
obj = Baz(num)
和第二个文件main.py
from app import foo
foo(10)
运行 文件 python main.py
给出了正确的输出。
现在在第二个文件中,我只是导入函数而不是 class,尽管我的函数的成功执行也需要 class。
导入函数时 Python 会自动导入 运行 该函数所需的所有其他内容,还是会自动在当前目录中搜索 class?
Python 不会自动执行任何这些操作。
当您从模块(在本例中为 app
模块)导入某些内容时,Python 首先 运行 相应文件中的所有代码(app.py
).您编写的文件 app.py
中的代码做了两件事:
- 定义 class
Baz
- 定义函数
foo
当函数 foo
运行s 时,Python 在 foo
所属的模块中查找 Baz
,并且仅在该模块中查找。 (好吧,它还检查函数 foo
中定义的局部变量,但除了 obj
之外你没有任何局部变量。)具体来说,它会查找 app.Baz
。如果您更改 main.py
以执行相同的搜索:
from app import foo
foo(10)
import app # same app that was already imported
print app.Baz
你会看到app.Baz
就是你在app.py
中定义的class。
如果您将 class Baz
的定义放在另一个文件中,并且如果您不导入该文件,Python 将不会 运行 它。这表明 Python 不会 自动导入依赖项。特别是,假设 app.py
包含
def foo(num):
obj = Baz(num)
并且baz.py
包含
class Baz():
def __init__(self, num):
self.a = num
print self.a
和main.py
不变。你会得到一个错误,因为 Python 没有 运行 定义 class Baz
.
正如@DavidZ 已经提到的,整个 Python 文件在我们导入时被编译。但是当解析函数体时会发生另一件特殊的事情,函数知道它应该在局部范围内寻找哪些变量以及它应该在全局范围内寻找哪些变量(当然也有自由变量)。
>>> import dis
>>> dis.dis(foo)
7 0 LOAD_GLOBAL 0 (Baz)
3 LOAD_FAST 0 (num)
6 CALL_FUNCTION 1
9 STORE_FAST 1 (obj)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
所以,这里 Baz
必须从全局范围获取。
But how to identify this global scope when we import app.py in another file?
好吧,每个函数都有一个附加的特殊属性 __globals__
,其中包含其实际的全局命名空间。因此,这就是 Baz
:
>>> foo.__globals__['Baz']
<class __main__.Baz at 0x10f6e1c80>
因此,应用程序的模块字典和 foo.__globals__
指向同一个对象:
>>>sys.modules['app'].__dict__ is foo.__globals__
True
因此,即使您在导入 foo
后在 main.py
中定义另一个名为 Baz
的变量,它仍然会访问实际的 Baz
.
来自 data-model page:
__globals__ func_globals
:
A reference to the dictionary that holds the function’s global variables — the global namespace of the module in which the function was defined.