Python中的import关键字如何工作?
假设我有3个文件:
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:未定义全局名称'a'
但是,sys.modules中的一个IS:
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在sys.modules中说它不知道什么是?
使用sys.modules是一种“正确”的方法来访问类和函数定义?
什么是导入模块的“正确”方式?
即从模块导入x
要么
导入模块
我想这是一个范围问题,如果你在你的构造函数中导入一个模块,你只能在你的构造函数中使用它,在import语句之后。
根据Python文档,
导入语句分两步执行:(1)找到一个模块,并在必要时进行初始化; (2) 在本地命名空间 (发生导入语句的范围)中定义一个或多个名称。
所以问题是,即使模块a
已经进口的,名字a
只被在的范围内绑定b.__init__
方法,而不是整个范围b.py
。 所以在b.test
方法,有没有这样的名字a
,所以你会得到一个NameError
。
您可能想阅读关于导入Python模块的文章,因为它有助于解释使用import
的最佳实践。
在你的情况,a是在sys.modules ..但不是在sys.modules中的所有东西都在b的范围内。 如果你想使用re,你也必须导入。
有条件的输入偶尔是可以接受的,但这不是其中的一种。 首先,在这种情况下,a和b之间的循环依赖是不幸的,应该避免(在Fowler的重构中有很多模式)。也就是说,没有必要有条件地在这里导入。
b应该简单地导入一个。 通过不直接在文件顶部导入它,你试图避免什么?
链接地址: http://www.djcxy.com/p/54795.html