我一直在努力理解导入包和子包在 Python 中是如何工作的。根据我对 realpython.com 的理解,一个包只是一个包含 python 模块和一个
__init__.py
文件的目录,如果您使用 __all__
声明。最重要的是,如果你想包含更多的子包,每个子包都应该是一个子目录,里面有一个import *
文件。所以,假设我正在做一个看起来像这样的项目,其中 __init__.py
是我要创建的包。
my_pckg/
我的理解是,如果我想使用
Project/
├── main.py
└── my_pckg/
├── __init__.py
├── functions.py
└── abc/
├── __init__.py
└── A.py
模块中的函数
func_1()
,我必须运行以下任何一个:functions
同样,如果我想从
import my_pckg.functions as pckg_fun
pckg_fun.func_1()
from my_pckg.functions import func_1
func_1()
子包的
func_A()
模块导入函数 A
,我所要做的就是使用以下任何选项:abc
现在,当我使用像 Numpy 这样的 Python 库时,我想使用 random 子包中的
import my_pckg.abc.A as pckg_A
pckg_A.func_A()
from my_pckg.abc.A import func_A
func_A()
函数,例如,我可以简单地做
randn()
而如果我运行以下代码片段
import numpy as np
np.random.randn(2)
或
import my_pckg as mp
mp.functions.func_1()
我收到这样的错误:
import my_pckg as mp
mp.abc.A.func_A()
或这个,分别
>>> mp.functions.func_1()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'my_pckg' has no attribute 'functions'
所以,我猜要么创建我认为的模块需要更多,要么我不理解像 NumPy 这样的模块实际上是如何工作的。
最后 Mitch Hedberg 的这个笑话真实地总结了我对这一切的感受:
他们说雪碧的配方是柠檬和酸橙,但我试着在家里做,不止于此。 [...]
导入了该子模块,则包子模块可作为其包的属性使用。当您第一次 >>> mp.abc.A.func_A()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'my_pckg' has no attribute 'abc'
时,NumPy 本身会导入自己的子模块,让您无需显式导入这些子模块即可访问它们。