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