Python中的import关键字是如何工作的?
假设我有三个文件:
a.py
from d import d
class a:
def type(self):
return "a"
def test(self):
try:
x = b()
except:
print "EXCEPT IN A"
from b import b
x = b()
return x.type()
b.py
import sys
class b:
def __init__(self):
if "a" not in sys.modules:
print "Importing a!"
from a import a
pass
def type(self):
return "b"
def test(self):
for modules in sys.modules:
print modules
x = a()
return x.type()
c.py
from b import b
import sys
x = b()
print x.test()
然后我运行 python c.py
结果Python报错说:
NameError: global name 'a' is not defined
但是,a确实在 sys.modules 里:
copy_reg
sre_compile
locale
_sre
functools
encodings
site
__builtin__
operator
__main__
types
encodings.encodings
abc
errno
encodings.codecs
sre_constants
re
_abcoll
ntpath
_codecs
nt
_warnings
genericpath
stat
zipimport
encodings.__builtin__
warnings
UserDict
encodings.cp1252
sys
a
codecs
os.path
_functools
_locale
b
d
signal
linecache
encodings.aliases
exceptions
sre_parse
os
我可以修改 b.py 让它变成:
x = a()
改成
x = sys.modules["a"].a()
这样Python就能顺利运行了。
这引出了几个问题:
为什么Python会说它不知道 a 是什么,尽管它在 sys.modules 里?
使用 sys.modules 访问类和函数定义算是“正确”的方式吗?
导入模块的“正确”方式是什么?
比如说
from module import x
或者
import module
4 个回答
在你的情况中,a已经在sys.modules里了……但是sys.modules里的所有东西并不都在b的作用范围内。如果你想用re这个模块,你也得把它导入进来。
有时候条件导入是可以接受的,但这次不适合。首先,a和b之间的循环依赖是个麻烦事,应该尽量避免(在Fowler的重构书里有很多解决这种问题的方法)。不过在这里其实没有必要使用条件导入。
b应该直接导入a。你为什么不直接在文件顶部导入它呢?
根据Python的文档,
导入语句的执行分为两个步骤:(1) 找到一个模块,并在必要时初始化它;(2) 在本地命名空间(也就是导入语句出现的范围)中定义一个或多个名称。
所以问题在于,虽然模块a
已经被导入,但名称a
只在b.__init__
方法的范围内被绑定,而不是在整个b.py
文件的范围内。因此在b.test
方法中,没有名称a
,所以你会遇到NameError
错误。
你可能想看看这篇关于导入Python模块的文章,它能帮助你理解使用import
时的最佳实践。
我想这可能是作用域的问题。如果你在构造函数里导入一个模块,那么你只能在这个构造函数里使用它,也就是在导入语句之后才能用。