用于导入模块时,Python上__init__中__all__的行为
我有一个以下形式的python包:
package
??? __init__.py
??? module_1.py
??? module_2.py
package
??? __init__.py
??? module_1.py
??? module_2.py
package ??? __init__.py ??? module_1.py ??? module_2.__all__ = ["module_1", "module_2"]py
package ??? __init__.py ??? module_1.py ??? module_2.__all__ = ["module_1", "module_2"]在 __init__.py 里面我有:
Module_1 是:
Module_2 是:
从文档中
__all__ = ["foo"] def foo(): pass我认为以下代码将导入
foo和Bar:但是,当
__all__ = ["Bar"] class Bar: pass我运行
pk.foo()它时会引发错误:(AttributeError: module 'package' has no attribute 'foo'对于 Bar 也是如此)。感谢这个答案,我知道要获得所需的行为,我可以将 __init__.py 更改为:
以上工作
import package as pk。
但是,我不明白 文档。线路:
如果一个包的 __init__.py 代码定义了一个名为 __all__ 的列表,它被认为是遇到 from package import * 时应该导入的模块名称列表
听起来像我原来的 __init__.py 应该工作(那个
__all__ = ["module_1", "module_2"])。也就是说,该行import package as pk应已导入模块module_1和module_2,这反过来又化妆foo和Bar使用。我错过了什么?
编辑:
我也试过完全使用文档中提到的内容。也就是说,使用
from package import *, 然后尝试使用package.foo()和foo(),但都没有奏效。第一个,
package.foo(),抛出错误NameError: 'package' is not defined.。第二个,foo(),抛出错误NameError: 'foo' is not defined.。一个工作示例看起来如何?.. __init__.py 的形式为 __all__ = ["module_1", "module_2"]。
回答
我将尝试总结从对我的问题、文档、我自己的测试和这篇文章的评论中获得的知识。
1)
__all__在__init__和 模块上表现不同1.1) 在一个模块内
当
_所有_is within a _module_, it determines what objects are made available when runningfrom 模块导入 *`。鉴于此包结构:
并给出以下代码
module_1:运行
from package.module_1 import *将使foo可用但不可用baz。此外,
foo可以使用 using 调用foo(),即不需要引用模块。1.2)内
__init__(我原来的问题)当
__all__在 内时__init__,它被认为是列表模块名称是应导入时,从包导入*遇到的。
运行
from package import *将有两个效果:
- 模块的脚本
__all__将被运行(它们被导入)。- 这些模块在命名空间中可用。
这意味着如果
__init__是以下形式:然后,运
__all__ = ["foo"] def foo(): pass def baz(): pass行
from package import *将运行的脚本module_1和module_2以及使这两个模块提供。所以,现在,foo里面的函数module_1可以调用 asmodule_1.foo()而不是package.module_1.foo()。但是,如果这是意图,那么使用
from package.module_1 import foo可能会更好。因为它foo可以作为foo().2)
from package import *不一样import package运行
from package import *有1.2)中提到的效果。但是,这不适用于运行import package:即module_1.foo()在这种情况下不起作用。3) 替代方法
__init__(以下是基于此职位)正如我在问题中提到,有一种替代方法
__init__,其中的对象,你要提供当用户呼叫from package import *被直接导入__init__。例如,
__init__可以包含以下代码:然后,当用户调用
from package import *模块 1 和 2 中的对象时,命名空间上的对象将可用。如果
module_1是1.1),则foo可以在不引用模块的情况下调用该函数。即foo()。但是,这同样不适用于baz.如2) 中所述,
from package import *与 不同import package。import package在这种情况下调用(使用 this__init__),使 foo 通过 可用package.foo(),而不仅仅是foo()。同样import package as pk使 foo 可用作pk.foo().这种方法可能比1.2) 的方法更可取,在1.2)中
foo可以通过module_1.foo().