MEMOO
MEMOO
Published on 2025-04-20 / 4 Visits
0
0

Python包(Package)

摘要:在本教程中,你学习了 Python 包以及如何使用它们来组织你的应用程序。

Python 包简介

假设你需要开发一个处理从订单到现金的销售流程的大型应用程序。

该应用程序将包含许多 模块,随着模块数量的增加,将所有模块保存在一个位置将变得困难。

你可能希望将模块有组织的放置在不同的项目位置中,这就是包发挥作用的地方。

包允许你以层次结构组织模块。

Python 组织包和模块的方式与操作系统组织文件夹和文件的方式类似。

要创建一个包,你需要创建一个新文件夹,并将相关模块放置在该文件夹中。

要 将包含 Python 文件的文件夹视为包,你需要在该文件夹中创建一个 __init__.py 文件。

注意,从 Python 3.3 开始,Python 引入了隐式命名空间包(implicit namespace packages)特性。这使得 Python 可以在没有 __init__.py 文件的情况下将一个文件夹视为包。

例如,下图展示了包含三个模块orderdeliverybilling)的 sales 包:

导入Python包

要导入一个包,你可以像下面这样使用 import 语句:

import package.module

要访问属于某个包的模块中的对象,你可以使用点号表示法(dot notation):

package.module.function

以下展示了如何从 sales 包中使用 orderdeliverybilling 模块中的函数:

# 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__ 的特殊列表中指定的所有模块。

例如,你可以像这样将 orderdelivery 模块放在 __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 中,你可以访问在 orderdelivery 模块中定义的函数。但是你看不到 billing 模块,因为它不在 __all__ 列表中。

子包(subpackage)

包可以包含子包。子包允许你进一步组织模块。

以下展示了包含三个子包的 salesorderdeliverybilling。每个子包都有对应的模块。

例如,你可以将所有与订单处理相关的其他模块放在 order 子包中:

你学到的有关包的所有知识同样适用于子包。

例如,要从 order 子包中导入一个函数,你可以使用以下导入语句:

# main.py
from sales.order import create_sales_order

create_sales_order()

总结

  • 一个 Python 包可以包含一个或多个模块。Python 使用文件夹和文件结构来管理包和模块。

  • 如果需要初始化包级数据,请使用 __init__.py 文件。

  • 使用 __all__ 变量来指定在导入包时将自动加载的模块。

  • 一个包可能包含子包。


Comment