当用于导入模块时,Python上的uuu init_uuuu中的uuu all_uuuuuu的行为

当用于导入模块时,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导入

我有一个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导入
但是,当我运行
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)更可取,其中