根据文档,import <modname>
结合了两种操作:
- 搜索名为
modname
的模块 - 如果找到,请创建并初始化模块对象,并将其绑定到导入范围中的名称
modname
但我找不到对from <modname> import <attr>
的类似解释。
问题
假设attr
是一个函数,它引用了modname
中未导入的一些其他属性。为什么当我们只导入attr
时,它仍然可以访问这些其他属性,即使它们没有导入?它只是通过闭包还是像import modname
中那样创建了一个模块对象?
示例
square.py:
num = 3
def squarenum():
return num**2
test.py:
from square import squarenum
squarenum() # prints 9 even though `num` wasn't imported
在上面的例子中,即使没有导入num
,squarenum
仍然可以访问num
,这是为什么?
函数对象本身维护对定义它的全局变量的引用。它们可在__globals__
属性处访问
$ cat t.py
x = 1
def f():
print(x)
>>> from t import f
>>> f.__globals__['x']
1
>>> f()
1
>>> # not that you should ever do this
>>> f.__globals__['x'] = 2
>>> f()
2