简体   繁体   English

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

[英]Python namespace change of `import package.sub_module; from package import *`

The Python documentation says Python文档

Consider this code: 考虑以下代码:

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

In this example, the echo and surround modules are imported in the current namespace because they are defined in the sound.effects package when the from...import statement is executed. 在此示例中,echo和surround模块在当前名称空间中导入,因为它们是在执行from ... import语句时在sound.effects包中定义的。 (This also works when __all__ is defined.) (这在定义__all__时也有效。)

I try the following code 我尝试以下代码

# package/
#     __init__.py
#     sub_module.py

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

When package/__init__.py is empty, the code works fine. package/__init__.py为空时,代码工作正常。 However, when package/__init__.py contains __all__ = [] , print(sub_module) will raise NameError . 但是,当package/__init__.py包含__all__ = []print(sub_module)将引发NameError What is (This also works when all is defined.) from the documentation means? 什么是(这在定义所有内容时也有效。)来自文档工具?


The codes: 代码:

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

In main.py: 在main.py中:

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

When package/__init__.py is empty, executing python3 main.py gets <module 'package.sub_module' from '/path/to/package/sub_module.py' package/__init__.py为空时,执行python3 main.py <module 'package.sub_module' from '/path/to/package/sub_module.py'获取<module 'package.sub_module' from '/path/to/package/sub_module.py' python3 main.py <module 'package.sub_module' from '/path/to/package/sub_module.py'

When package/__init__.py contains __all__ = [] , executing python3 main.py gets 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

If a module package defines __all__ , it is the list of module names that are imported by from package import * 如果模块package定义__all__ ,则它是from package import *的模块名称列表from package import *

So if you define __all__ as empty list, from package import * will import nothing. 因此,如果将__all__定义为空列表, from package import *将不会导入任何内容。

Try defining it like this: 尝试像这样定义它:

__all__ = ['sub_module']

Also note that you don't have to do from package import * to use sub_module 另请注意,您无需执行from package import *即可使用sub_module

You can also just do: 你也可以这样做:

import package.sub_module
print(package.sub_module)

Solution : you have __all__ set to empty list ie from package import * basically imports nothing 解决方案 :你有__all__设置为空列表,即from package import *基本上没有输入

set it to __all__ = ['submodule'] in __init__.py __init__.py中将其设置为__all__ = ['submodule']


What exactly is __all__ ? 究竟是什么__all__

In simplest words all help customizing the from package import * ie with all we can set what will be imported and what not. 用最简单的话所有的自定义帮助from package import *即与所有我们可以设置哪些将被导入,什么不是。

From the docs : 来自文档

The public names defined by a module are determined by checking the module's namespace for a variable named all ; 模块定义的公共名称是通过检查模块名称为all的变量的命名空间来确定的; if defined, it must be a sequence of strings which are names defined or imported by that module. 如果已定义,则它必须是一个字符串序列,这些字符串是由该模块定义或导入的名称。 The names given in all are all considered public and are required to exist. 所有名称被认为是公开的,并且必须存在。 If all is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ('_'). 如果未定义all ,则公共名称集包括在模块命名空间中找到的所有名称,这些名称不以下划线字符('_')开头。 all should contain the entire public API. all应该包含整个公共API。 It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module). 它旨在避免意外导出不属于API的项目(例如在模块中导入和使用的库模块)。


One important thing to note here is - Imports without * are not affected by __all__ ie Members that are not mentioned in __all__ are accessible from outside the module using direct import - from <module> import <member> . 这里要注意的一件重要的事情是- 没有进口*不受__all__没有被提及,即成员__all__是使用直接进口模块外部访问- from <module> import <member>

An Example : the following code in a module.py explicitly exports the symbols foo and bar : 示例module.py的以下代码显式导出符号foobar

__all__ = ['foo', 'bar']

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

These symbols can then be imported like so: 然后可以像这样导入这些符号:

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

If you define __all__ , then only the attributes mentioned there will be imported via * , while the excluded ones have to be imported explicitly . 如果定义__all__ ,那么只有那里提到的属性将通过*导入,而排除的属性必须明确导入。 So either use 所以要么使用

from package import submodule

or if you really want to use the (discouraged!) from package import * , declare 或者,如果你真的想使用from package import * (气馁!),请声明

__all__ = ['submodule']

in package . package Note how tedious it will become to keep this up-to-date... 请注意保持最新状态会变得多么乏味......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM