我有一个以下形式的python包:
package
??? __init__.py
??? module_1.py
??? module_2.py
Run Code Online (Sandbox Code Playgroud)
在 __init__.py 里面我有:
package
??? __init__.py
??? module_1.py
??? module_2.py
Run Code Online (Sandbox Code Playgroud)
Module_1 是:
__all__ = ["module_1", "module_2"]
Run Code Online (Sandbox Code Playgroud)
Module_2 是:
__all__ = ["foo"]
def foo(): pass
Run Code Online (Sandbox Code Playgroud)
从文档中我认为以下代码将导入foo和Bar:
__all__ = ["Bar"]
class Bar: pass
Run Code Online (Sandbox Code Playgroud)
但是,当我运行pk.foo()它时会引发错误:(AttributeError: module 'package' has no attribute 'foo'对于 Bar 也是如此)。
感谢这个答案,我知道要获得所需的行为,我可以将 __init__.py 更改为:
import package as pk
Run Code Online (Sandbox Code Playgroud)
以上工作。
但是,我不明白 文档。线路:
如果一个包的 __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"]。
我将尝试总结从对我的问题、文档、我自己的测试和这篇文章的评论中获得的知识。
__all__在__init__和 模块上表现不同当_所有_ is within a _module_, it determines what objects are made available when runningfrom 模块导入 *`。
鉴于此包结构:
package
??? __init__.py
??? module_1.py
??? module_2.py
Run Code Online (Sandbox Code Playgroud)
并给出以下代码module_1:
package
??? __init__.py
??? module_1.py
??? module_2.py
Run Code Online (Sandbox Code Playgroud)
运行from package.module_1 import *将使foo可用但不可用baz。
此外,foo可以使用 using 调用foo(),即不需要引用模块。
__init__(我原来的问题)当__all__在 内时__init__,
它被认为是列表模块名称是应导入时,从包导入*遇到的。
运行from package import *将有两个效果:
__all__将被运行(它们被导入)。这意味着如果__init__是以下形式:
__all__ = ["foo"]
def foo(): pass
def baz(): pass
Run Code Online (Sandbox Code Playgroud)
然后,运行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().
from package import *不一样import package运行from package import *有1.2)中提到的效果。但是,这不适用于运行import package:即module_1.foo()在这种情况下不起作用。
__init__(以下是基于此职位)正如我在问题中提到,有一种替代方法__init__,其中的对象,你要提供当用户呼叫from package import *被直接导入__init__。
例如,__init__可以包含以下代码:
__all__ = ["module_1", "module_2"]
Run Code Online (Sandbox Code Playgroud)
然后,当用户调用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().
Bho*_*yar -3
代码中的关键问题是您__all__在子模块中定义了。它允许仅导出该模块,但此类模块在您的目录中不可用。它们是您想要使用的定义。
因此,只需从子模块中删除它们即可使其正常工作。
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |