封闭导入如何在Python中工作

时间:2013-01-10 22:05:23

标签: python

这是我在pythion的进口中无法弄清楚的事情。 假设我有一个模块'a',用'import b'导入模块'b' 然后,有一个模块'c'导入模块'a'。 名称'b'的名称是否可以在'c'中找到?

我已经检查过它实际上取决于你如何导入模块'c'中的模块'a'。 如果您执行“导入”,则“c”中的名称将不会出现在“c”中。 但是,如果您“从导入*”进行,那么它们将可用。 有人可以澄清区别吗?

3 个答案:

答案 0 :(得分:4)

如果您仔细考虑这些命令实际执行的操作,那就非常简单了。

a.py:

import b
foo = 0

b.py:

bar = 1

c.py:

import a

来自c,您不能只说foo,您必须说a.fooa中的每个名称都是如此 - 常量,变量,函数,类甚至模块。这包括b

所以,你不能说bara.bar,但你可以说a.b.bar

现在,如果你改变它会怎么样:

a.py:

from b import *
foo = 0

b.py:

bar = 1

c.py:

from a import *

from b import *执行的操作是将b命名空间中的所有内容放入a的命名空间中,以便您可以直接在bar内查找a {1}}。然后,当你执行from a import *时,它会占用a命名空间中的所有内容,并将其放入c中,就像你可以foo一样,也可以bar

这就是为什么你通常不希望在顶级脚本中的任何地方from b import * - 因为你的命名空间全部合并在一起。

这也是为什么你可以限制*使用__all__获取的内容:

a.py:

from b import *
__all__ = ['foo']
foo = 0

b.py:

bar = 1

c.py:

from a import *

现在,从c开始,您可以c.foo,但不能c.bar

因此,a可以from b import *来实现自己的功能,而不会将b的所有内部内容暴露给用户。

答案 1 :(得分:3)

import语句导致执行模块,所有变量都保存在执行模块的命名空间中。也就是说,如果您import a,那么a的所有变量都将位于a.[variable]之下。 from关键字的行为略有不同:它将变量放在当前命名空间中。例如,from a import foo将变量foo放在当前名称空间中。 from a import *将所有变量从a导入当前名称空间。 as关键字允许您在导入变量时重命名变量;因此from a import foo as bar允许您访问a.foo,但您必须将其称为bar; import a.foo as foo相当于from a import foo

答案 2 :(得分:1)

比上面更具体的例子:

a.py

import b
bar = 'bar'

b.py

foo = 'foo'

c.py

import a


try:
   print(b.foo)
except:
   print('No `b` in current namespace')

try:
   print(a.bar)
except:
   print('No `a` in current namespace')

try:
   print(a.b.foo)
except:
   print('No `a` or `a.b` in current namespace')

这应该打印(按顺序):

No `b` in current namespace
bar
foo

换句话说,b只能通过访问a的命名空间来获取