当用于导入模块时,Python上的uuu init_uuuu中的uuu all_uuuuuu的行为
我有一个python包,格式如下:当用于导入模块时,Python上的uuu init_uuuu中的uuu all_uuuuuu的行为,python,python-3.x,Python,Python 3.x,我有一个python包,格式如下: package ├── __init__.py ├── module_1.py └── module_2.py 在_uinit _; py.py内,我有: \uuuuuu all\uuuuu=[“模块1”、“模块2”] 模块1是: \uuuuuuuuuuuuuuuuuuu=[“foo”] def foo():传递 模块2是: \uuuuuuuuuuuuuuuuuuu=[“条”] 级别栏:通过 从中,我认为以下代码将导入foo和Bar: 将包作为pk导入
package
├── __init__.py
├── module_1.py
└── module_2.py
在_uinit _; py.py内,我有:
\uuuuuu all\uuuuu=[“模块1”、“模块2”]
模块1是:
\uuuuuuuuuuuuuuuuuuu=[“foo”]
def foo():传递
模块2是:
\uuuuuuuuuuuuuuuuuuu=[“条”]
级别栏:通过
从中,我认为以下代码将导入foo
和Bar
:
将包作为pk导入
但是,当我运行pk.foo()
时,它会抛出一个错误:AttributeError:module'package'没有属性'foo'
(对于Bar也是如此)
感谢您的回答,我知道要获得所需的行为,我可以将_uinit_uuuuuuy.py更改为:
from.module_1导入*
from.module_2导入*
以上工作
但是,我不理解。台词:
如果包的_init _uuuuuuupy.py代码定义了一个名为_all uuuuuuuuuu的列表,则该列表将被视为遇到“从包导入”时应导入的模块名称列表
听起来像是我原来的uuu init_uuuuuuuuuuuy.py应该可以工作(带有\uuuuuuu all\uuuuuuuuuu=[“模块1”、“模块2”]
)。也就是说,行导入包作为pk
应该已经导入了模块模块_1
和模块_2
,这反过来使foo
和条形码可用
我错过了什么
编辑:
我还尝试使用文档中提到的内容。也就是说,使用包导入中的*
,然后尝试使用package.foo()
和foo()
,但都不起作用
第一个,package.foo()
,抛出错误NameError:“package”未定义。
。第二个,foo()
,抛出错误NameError:“foo”未定义。
一个工作示例是什么样子的?。。其中uuu init uuuuuy.py的形式为uuu all uuuuu=[“模块1”、“模块2”]。代码中的关键问题是您在子模块中定义了\uuuu all uuuuuuu
。它只允许导出该模块,但该模块在您的目录中不可用。它们是您要使用的定义
因此,只要将它们从子模块中删除,您就可以让它工作。我将尝试总结从对我的问题的评论、我自己的测试和帖子中获得的知识
1) \uuuuuuuuuuuuuuuuuu
在\uuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>和模块上的行为不同
1.1)在模块内
当\uu
所有都在一个模块内时,它确定从模块导入*运行时哪些对象可用
鉴于此包结构:
package
├── __init__.py
├── module_1.py
└── module_2.py
并给出了模块1的以下代码:
\uuuuuuuuuuuuuuuuuuu=[“foo”]
def foo():传递
def baz():通过
从package.module_1 import*
运行,将使foo
可用,而不是baz
此外,然后可以使用foo()
调用foo
,即不需要引用模块
1.2)在\uuuuu init\uuuuu
内(我的原始问题)
当\uuuuuuuuuuuuuuuuu
在\uuuuuu init\uuuuuuuuuuuuu
内时
当遇到来自包导入的时,应导入的模块名称列表
从包导入运行*
将产生两种效果:
将运行\uuuuu all\uuuu
中模块的脚本(它们将被导入)
这些模块在名称空间中可用
这意味着如果\uuuu init\uuuu
的形式为:
package
├── __init__.py
├── module_1.py
└── module_2.py
\uuuuuu all\uuuuu=[“模块1”、“模块2”]
然后,从包导入运行*
将运行module_1
和module_2
的脚本,并使这两个模块都可用。因此,现在可以将module_1
中的函数foo
称为module_1.foo()
,而不是package.module_1.foo()
但是,如果这是目的,那么使用package.module_1 import foo中的可能会更好。因为它使foo
可以作为foo()
访问
2) 来自包导入的与导入包的不同
从包导入运行*
具有1.2)中提到的效果。但是,对于运行导入包
,情况并非如此:即模块_1.foo()
在这种情况下不起作用
3) \uuuu init\uuuu
(以下是基于post)正如我在问题中提到的,有一种替代方法可用于\uuuuu init\uuuuu
,在这种方法中,当用户从package import*
调用时,要使其可用的对象直接导入\uuuu init\uuuuuu
中
例如,\uuuuuu init\uuuu
可以包含以下代码:
from.module_1导入*
from.module_2导入*
然后,当用户从package import*
调用时,模块1和2中的对象将在名称空间中可用
如果module_1
是1.1)的函数,则可以调用函数foo
,而无需引用该模块。i、 e.foo()
。但是,同样的方法不适用于baz
如2)中所述,来自程序包导入的与导入程序包的不同。在此场景中调用import package
(使用此\uuuu init\uuuu
),可以通过package.foo()
,而不是foo()
。类似地,import package as pk
使foo可用作pk.foo()
这种方法可能比1.2)更可取,其中