摘要:在本教程中,你学习了 Python 包以及如何使用它们来组织你的应用程序。
Python 包简介
假设你需要开发一个处理从订单到现金的销售流程的大型应用程序。
该应用程序将包含许多 模块,随着模块数量的增加,将所有模块保存在一个位置将变得困难。
你可能希望将模块有组织的放置在不同的项目位置中,这就是包发挥作用的地方。
包允许你以层次结构组织模块。
Python 组织包和模块的方式与操作系统组织文件夹和文件的方式类似。
要创建一个包,你需要创建一个新文件夹,并将相关模块放置在该文件夹中。
要 将包含 Python 文件的文件夹视为包,你需要在该文件夹中创建一个 __init__.py
文件。
注意,从 Python 3.3 开始,Python 引入了隐式命名空间包(implicit namespace packages)特性。这使得 Python 可以在没有
__init__.py
文件的情况下将一个文件夹视为包。
例如,下图展示了包含三个模块orderdelivery
和 billing
)的 sales
包:
导入Python包
要导入一个包,你可以像下面这样使用 import
语句:
import package.module
要访问属于某个包的模块中的对象,你可以使用点号表示法(dot notation):
package.module.function
以下展示了如何从 sales
包中使用 orderdelivery
和 billing
模块中的函数:
# main.py
import sales.order
import sales.delivery
import sales.billing
sales.order.create_sales_order()
sales.delivery.create_delivery()
sales.billing.create_billing()
为了使代码更加简洁,你可以使用以下语句从模块中导入一个函数:
from <module> import <function>
例如:
# main.py
from sales.order import create_sales_order
from sales.delivery import create_delivery
from sales.billing import create_billing
create_sales_order()
create_delivery()
create_billing()
可以在导入对象时对其进行重命名:
# main.py
from sales.order import create_sales_order as create_order
from sales.delivery import create_delivery as start_delivery
from sales.billing import create_billing as issue_billing
create_order()
start_delivery()
issue_billing()
在这个例子中,我们将……
create_sales_order
重命名为create_order
,create_delivery
重命名为start_delivery
,以及
create_billing
重命名为issue_billing
。
初始化包
按照惯例,当你导入一个包时,Python 会执行该包中的 __init__.py
。
因此,你可以在 __init__.py
文件中放置代码来初始化包级数据。
以下示例在 sales
包的 __init__.py
中定义了一个默认税率:
# __init__.py
# default sales tax rate
TAX_RATE = 0.07
从 main.py
文件中,你可以这样访问 sales
包中的 TAX_RATE
:
# main.py
from sales import TAX_RATE
print(TAX_RATE)
除了初始化包级数据外__init__.py
还允许你自动从包中导入模块。
例如,在 __init__.py
中,如果你放置以下语句:
# __init__.py
# import the order module automatically
from sales.order import create_sales_order
# default sales tax rate
TAX_RATE = 0.07
并且从 main.py
文件中导入 sales
包后create_sales_order
函数将自动可用,如下所示:
# main.py
import sales
sales.order.create_sales_order()
from <package> import *
当你使用语句从包中导入所有对象时:
from <package> import *
Python 会查找 __init__.py
文件。
如果 __init__.py
文件存在,它将加载该文件中一个名为 __all__
的特殊列表中指定的所有模块。
例如,你可以像这样将 order
和 delivery
模块放在 __all__
列表中:
# __init__.py
__all__ = [
'order',
'delivery'
]
并在 main.py
中使用以下导入语句:
# main.py
from sales import *
order.create_sales_order()
delivery.create_delivery()
# cannot access the billing module
从 main.py
中,你可以访问在 order
和 delivery
模块中定义的函数。但是你看不到 billing
模块,因为它不在 __all__
列表中。
子包(subpackage)
包可以包含子包。子包允许你进一步组织模块。
以下展示了包含三个子包的 sales
包orderdelivery
和 billing
。每个子包都有对应的模块。
例如,你可以将所有与订单处理相关的其他模块放在 order
子包中:
你学到的有关包的所有知识同样适用于子包。
例如,要从 order
子包中导入一个函数,你可以使用以下导入语句:
# main.py
from sales.order import create_sales_order
create_sales_order()
总结
一个 Python 包可以包含一个或多个模块。Python 使用文件夹和文件结构来管理包和模块。
如果需要初始化包级数据,请使用
__init__.py
文件。使用
__all__
变量来指定在导入包时将自动加载的模块。一个包可能包含子包。