How does import keyword in python actually work?

Let's say I have 3 files:

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()

and run python c.py

Python comes back complaining:

NameError: global name 'a' is not defined

But, a IS in 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

And I can alter b.py such that:

x = a()
changes to
x = sys.modules["a"].a()

And python will happily run that.

A couple questions arise from this:

Why does python say it doesn't know what a is, when it is in sys.modules?
Is using sys.modules a "proper" way to access class and function definitions?
What is the "right" way to import modules?
ie from module import x
or
import module


我想这是一个范围问题,如果你在你的构造函数中导入一个模块,你只能在你的构造函数中使用它,在import语句之后。


According to the Python documentation,

Import statements are executed in two steps: (1) find a module, and initialize it if necessary; (2) define a name or names in the local namespace (of the scope where the import statement occurs).

So the problem is that even though module a has been imported, the name a has only been bound in the scope of the b.__init__ method, not the entire scope of b.py . So in the b.test method, there is no such name a , and so you get a NameError .

You might want to read this article on importing Python modules, as it helps to explain best practices for working with import s.


In your case, a is in sys.modules.. but not everything in sys.modules is in b's scope. If you want to use re, you'd have to import that as well.

Conditional importing is occasionally acceptable, but this isn't one of those occasions. For one thing, the circular dependency between a and b in this case is unfortunate, and should be avoided (lots of patterns for doing so in Fowler's Refactoring).. That said, there's no need to conditionally import here.

b ought to simply import a. What were you trying to avoid by not importing it directly at the top of the file?

链接地址: http://www.djcxy.com/p/54796.html

上一篇: Python:从其他脚本读取和执行行(或复制它们)?

下一篇: Python中的import关键字如何工作?