导入包和子包实际上是如何工作的?



我一直在尝试理解在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

我的理解是,如果我想使用functions模块中的func_1()函数,我必须运行以下任何一个:

import my_pckg.functions as pckg_fun
pckg_fun.func_1()
from my_pckg.functions import func_1
func_1()

同样,如果我想从abc子包的A模块导入函数func_A(),我所要做的就是使用以下任何一个选项:

import my_pckg.abc.A as pckg_A
pckg_A.func_A()
from my_pckg.abc.A import func_A
func_A()

现在,当我使用Numpy等Python库并且我想使用随机子包中的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'

或者这个

>>> 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这样的模块是如何实际工作的。

最后,Mitch Hedberg的这个笑话真实地总结了我对这一切的感受:

他们说雪碧的配方是柠檬和酸橙,但我试着在家里做,还有更多的东西。[…]

__init__.py中添加您想要从该模块中使用的东西的import语句,当您只导入该模块时

使用您的示例,在my_pckg/__init__.py中,您将拥有

import functions
import abc.A

在那之后,你应该能够做你所描述的没有任何问题。

编辑:在包内导入的最佳实践略有不同。即使模块在同一文件夹中,您也应该像这样从.导入模块,而不是直接导入:

from . import functions
from abc import A

第二行的副作用是您将直接调用mp.A.func_A()而不是mp.abc.A.func_A()

如果程序中的任何代码

都导入了该子模块,那么包子模块可以作为其包的属性使用。当您第一次使用import numpy时,NumPy自己导入了自己的子模块,让您无需显式导入这些子模块即可访问它们:

from . import linalg
from . import fft
from . import polynomial
from . import random
from . import ctypeslib
from . import ma

相关内容

  • 没有找到相关文章

最新更新