Python命名空间更改`import package.sub_module;从包导入*`

时间:2016-08-30 05:55:44

标签: python

Python documentation

  

考虑以下代码:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *
  

在此示例中,回显和环绕模块将导入   当前命名空间,因为它们是在sound.effects中定义的   执行from ... import语句时的包。 (这也有效   当__all__被定义时。)

我尝试以下代码

# package/
#     __init__.py
#     sub_module.py

import package.sub_module
from package import *
print(sub_module)

package/__init__.py为空时,代码工作正常。但是,当package/__init__.py包含__all__ = []时,print(sub_module)会引发NameError。 什么是(这在所有定义时也有效。)来自文档意味着什么?

代码:

package/
    __init__.py
    sub_module.py # empty file
main.py

在main.py中:

import package.sub_module
from package import *
print(sub_module)

package/__init__.py为空时,执行python3 main.py     <module 'package.sub_module' from '/path/to/package/sub_module.py'

package/__init__.py包含__all__ = []时,执行python3 main.py获取

Traceback (most recent call last):
File "main.py", line 3, in <module>
    print(sub_module)
NameError: name 'sub_module' is not defined

3 个答案:

答案 0 :(得分:2)

如果模块package定义__all__,则它是由from package import *

导入的模块名称列表

因此,如果您将__all__定义为空列表,from package import *将不会导入任何内容。

尝试像这样定义:

__all__ = ['sub_module']

另请注意,您无需from package import *即可使用sub_module

您也可以这样做:

import package.sub_module
print(package.sub_module)

答案 1 :(得分:1)

解决方案:您将__all__设置为空列表,from package import *基本上不会导入任何内容

__all__ = ['submodule']

中将其设为__init__.py
  

究竟是什么 __ all __

简单来说,所有有助于自定义from package import *,即所有,我们可以设置要导入的内容和不导入的内容。

来自docs

  

模块定义的公共名称通过检查确定   模块名为所有的变量的命名空间;如果定义,它必须   是一系列字符串,由其定义或导入的名称   模块。 所有中提供的名称都被视为公开名称   要求存在。如果未定义所有,则为公共名称集   包括模块命名空间中找不到的所有名称   带下划线字符('_')。 所有应该包含整个   公共API。它旨在避免意外导出的物品   不是API的一部分(例如导入的库模块)   并在模块中使用。)

此处需要注意的一件重要事项是 - 没有*的导入不受__all__ 的影响,即__all__中未提及的成员可以从外部访问使用直接导入的模块 - from <module> import <member>

示例module.py中的以下代码明确导出符号foobar

__all__ = ['foo', 'bar']

waz = 5
foo = 10
def bar(): return 'bar'

然后可以像这样导入这些符号:

from foo import *

print foo
print bar

# now import `waz` will trigger an exception, 
# as it is not in the `__all__`, hence not a public member.
print waz

答案 2 :(得分:0)

如果您定义__all__,则所提及的属性将通过*导入,而排除的属性必须明确导入。所以要么使用

from package import submodule

或者如果你真的想要使用(气馁!)from package import *,请声明

__all__ = ['submodule']
package中的

。请注意保持最新状态会变得多么乏味......