Python:为什么导入的模块不能引用另一个导入的模块?

Wil*_*ton 10 python import module

main.py:

import subone
import subtwo
Run Code Online (Sandbox Code Playgroud)

subone.py:

a = 'abc'
Run Code Online (Sandbox Code Playgroud)

subtwo.py:

print subone.a
Run Code Online (Sandbox Code Playgroud)

跑步python main.py投掷a NameError: name 'subone' is not defined.我希望它打印'abc'.

重构它以使用from import和类没有帮助:

main.py:

from subone import *   # Only using from X import * for example purposes.
from subtwo import *

print 'from main.py:', a.out
Run Code Online (Sandbox Code Playgroud)

subone.py:

class A:
    out = 'def'

a = A()
Run Code Online (Sandbox Code Playgroud)

subtwo.py:

# This throws NameError: name 'a' is not defined
print a.out

# This throws NameError: name 'A' is not defined
b = A()
print b.out
Run Code Online (Sandbox Code Playgroud)

但它 "从main.py:高清"打印.(它在使用时import也有效.)

为什么这样工作?似乎一旦subone导入,它应该是可用的subtwo.

这是因为导入的模块相互依赖而不通过"父"模块是不好的编程?还有另一种标准方法吗?

更新:

我现在明白了,第一个例子是行不通的,因为行print subone.a不能识别的名字subone,它不存在subtwo命名空间(即使它是在main.py的),并且它正在从模块中调用subtwo.这可以通过import subone在顶部使用来修复subtwo.py- 它不会重新加载模块,但会将其添加到subtwo命名空间,因此subtwo可以使用它.

但是这个怎么样:

main.py:

from subone import Nugget
from subtwo import Wrap

wrap = Wrap()
print wrap.nugget.gold
Run Code Online (Sandbox Code Playgroud)

subone.py:

class Nugget:
    gold = 'def'
Run Code Online (Sandbox Code Playgroud)

subtwo.py:

class Wrap:
    nugget = Nugget()
Run Code Online (Sandbox Code Playgroud)

我认为既然WrapNugget都直接加载到main命名空间,他们将使用main的命名空间并能够相互引用,但它会抛出一个NameError: name 'Nugget' is not defined.是IT因为在被加载到命名空间之前Wrap从命名空间 进行评估/检查?subtwomain

pyf*_*unc 6

如果您以这种方式修改了subtwo.py,那么它将起作用

import subone
print subone.a
Run Code Online (Sandbox Code Playgroud)

当你在subtwo.py中执行subone.a时,你试图访问subtwo.py和命名空间"subone"中的命名空间subone,应该有一个属性"a".

当你这样做 - 在subtwo.py中导入subone时,subone被添加到命名空间,subone命名空间有属性a.所以subone.a会起作用.

我还建议您使用dir()来查看如何添加命名空间.

在subtwo.py中,您可以执行以下操作:

print dir()
import subone
print dir()
print subone.a
Run Code Online (Sandbox Code Playgroud)

同样,尝试在导入语句之前和之后添加"print dir()",这个想法应该变得清晰.

"import x"将"x"添加到当前模块名称空间,而"from x import*"将所有模块级属性直接添加到当前模块名称空间

因此,在上面的main.py,subone.py和subtwo.py的第一个示例中,main.py中的命名空间将包含'subone'和'subtwo',而subtwo.py将具有空命名空间,并且无法访问subone.a .

[编辑:更多解释]请考虑以下文件:main.py

print "Before importing subone : ", dir()
import subone
print "After importing subone and before importing subtwo: ",  dir()
import subtwo
print "After importing subone and subtwo: ", dir()
Run Code Online (Sandbox Code Playgroud)

subone.py

a = 'abc'
Run Code Online (Sandbox Code Playgroud)

subtwo.py

print dir()
import subone
print "module level print: ", subone.a
print dir()
def printX():
    print subone.a
Run Code Online (Sandbox Code Playgroud)

并运行main.py的输出:

Before importing subone :  ['__builtins__', '__doc__', '__file__', '__name__', '__package__']
After importing subone and before importing subtwo:  ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone']
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
module level print:  abc
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone']
After importing subone and subtwo:  ['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'subone', 'subtwo']
Run Code Online (Sandbox Code Playgroud)

一些观察

  1. 您会注意到导入模块subtwo.py时,会立即执行print语句.
  2. 因此,当在main.py中导入subone和subtwo时,main.py的命名空间会被扩充.
  3. 这并不意味着将增加subtwo的命名空间.所以"a"只能通过subone.a在main.py中使用
  4. 当我们在subtwo.py中导入subone时,subwo的命名空间用subone增加,而subow.py中的模块subone属性a可通过subone.a获得.