这是我在 pythion 的进口中无法完全弄清楚的东西。假设我有一个模块“a”,它使用“import b”导入模块“b”然后,有一个模块“c”导入模块“a”。模块“b”的名称是否可以在“c”中使用?
我已经检查过它实际上取决于您如何在模块“c”中导入模块“a”。如果您执行“导入 a”,则“b”中的名称将无法在“c”中使用。但是,如果您执行“从导入 *”,那么它们将可用。有人可以澄清一下区别吗?
这是我在 pythion 的进口中无法完全弄清楚的东西。假设我有一个模块“a”,它使用“import b”导入模块“b”然后,有一个模块“c”导入模块“a”。模块“b”的名称是否可以在“c”中使用?
我已经检查过它实际上取决于您如何在模块“c”中导入模块“a”。如果您执行“导入 a”,则“b”中的名称将无法在“c”中使用。但是,如果您执行“从导入 *”,那么它们将可用。有人可以澄清一下区别吗?
如果您仔细考虑这些命令的实际作用,那就很简单了。
一个.py:
import b
foo = 0
b.py:
bar = 1
c.py:
import a
从c
,你不能只说foo
,你必须说a.foo
。a
常量、变量、函数、类甚至模块中的每个名称都是如此。这包括b
.
所以,你不能说bar
or a.bar
,但你可以说a.b.bar
。
现在,如果您像这样更改它会怎样:
一个.py:
from b import *
foo = 0
b.py:
bar = 1
c.py:
from a import *
这样from b import *
做是将 's 名称空间中的所有内容b
,并将其放入a
's 名称空间中,因此您可以直接bar
从inside 中说a
。然后,当你这样做时from a import *
,它会将 's 命名空间中的所有内容a
放入c
's 中,所以就像你可以做的那样foo
,你也可以做bar
.
这就是为什么您通常不想from b import *
在除了顶级脚本之外的任何地方做任何事情——因为您的命名空间会全部合并在一起。
这也是为什么您可以限制使用以下内容的*
原因__all__
:
一个.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
内部结构暴露给用户。
该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
。
比上面更具体的例子:
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 使用,但只能通过访问a
的命名空间