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

上一篇: How does import keyword in python actually work?

下一篇: Why does this multiprocessing code fail?