❏ 包是一种组织模块的方式,包中可以包含:各种模块、子包、其他资源等。
❏ 在Python中,『包含__init__.py的文件夹』就是一个包(Package)。
❏ 通常会把『某个特定功能相关的所有模块』放入一个包中。
❏ 使用包可以进一步提升代码的:可维护性、可复用性,便于管理大型项目。
❏ 一个模块就是一个.py文件,包是用来“管理模块”的目录(文件夹)。
❏ 一个包可以有多个模块,也可以有多个子包。
Python中的包分为三类:
Lib目录下,可直接导入使用,更多信息请阅读官方文档。下面是一个标准库包的使用示例:from collections import Counter
scores = [90, 85, 88, 93, 99, 100, 100, 98, 97, 90, 67, 59]
stat_result = Counter(scores)
print('分数统计结果如下:')
print(stat_result)
pip这个python的包管理工具从PyPi这个官方推荐和维护的包发布和包分发平台下载安装的开发者开发的包。由于这块内容比较重要,专门通下一篇文章来详细介绍。包的命名有以下注意点:
❏ 要符合标识符命名规范。
❏ 包名区分大小写(建议全部使用小写字母)。
❏ 不要与标准库包同名。
创建如下文件结构,由于trade文件夹中包含了__init__.py文件,所以trade就可以称之为『包』。
└──trade/
├── __init__.py
├── order.py # 订单模块
└── pay.py # 支付模块
各文件内容如下:
# file: trade/__init__.py
# 该文件暂时留白,不编写任何代码,后面会对该文件详细讲解
# file: trade/order.py
# 订单最大金额
max_order_amount = 10000
# 创建订单
def create_order():
print('订单创建成功!')
# 取消订单
def cancel_order():
print('订单已被取消!')
# 提示信息
def show_info():
print('我是来自【订单】模块的提示!')
# file: trade/pay.py
# 支付超时时间
timeout = 1800
# 微信支付
def wechat_pay():
print('微信支付成功!')
# 支付宝支付
def ali_pay():
print('支付宝支付成功!')
# 提示信息
def show_info():
print('我是来自【支付】模块的提示!')
❏ __init__.py是包的初始化文件,在包被导入时, __init__.py会被自动调用。
❏ __init__.py中可以编写一些包的初始化逻辑。
❏ __init__.py中所定义的内容,会被from 包名 import *的形式全部引入。
❏ __init__.py中也可以使用__all__来控制包中的哪些模块可以被from 包名 import *引入。
1、import 包名.模块名
import trade.order
import trade.pay
trade.order.create_order()
trade.pay.wechat_pay()
2、import 包名.模块名 as 别名
import trade.order as o
import trade.pay as p
o.create_order()
p.wechat_pay()
3、from 包名.模块名 import 具体内容
from trade.order import max_order_amount, create_order
from trade.pay import timeout, wechat_pay
print('最大订单金额:' + str(max_order_amount))
create_order()
print('支付超时时间:' + str(timeout))
wechat_pay()
4、from 包名.模块名 import 具体内容 as 别名
from trade.order import max_order_amount as max_amt, create_order as c_order
from trade.pay import timeout as tm_out, wechat_pay as wxpay
print('最大订单金额限制:' + str(max_amt))
c_order()
tm_out = 5
print('订单支付时限:' + str(tm_out) + '秒')
for i in range(tm_out):
print(f'\t{i + 1}秒')
sleep(1)
wxpay()
5、from 包名.模块名 import *
from trade.order import *
print(f'最大订单金额限制:{max_order_amount}')
create_order()
cancel_order()
show_info()
print()
from trade.pay import *
print(f'订单支付时限:{timeout}秒')
wechat_pay()
ali_pay()
show_info()
6、from 包名 import 模块名
from trade import order, pay
order.create_order()
pay.wechat_pay()
7、from 包名 import 模块名 as 别名
from trade import order as o, pay as p
o.create_order()
p.wechat_pay()
8、from 包名 import *
注意:想通过这种方式进行导入,就必须在__init__.py中定义好具体内容。
如果没定义__init.py的内容,则无法引用包中的模块资源,强行引用则导致报错。
那我们配置__init__.py文件的内容如下:
# file: trade/__init__.py
print('我是__init__.py')
version = 1.0
from . import order
from . import pay
__all__ = ('order', 'pay', 'version')
导入测试代码如下:
from trade import *
print(f'trade包的版本号:{version}')
order.create_order()
print(order.max_order_amount)
pay.wechat_pay()
print(pay.timeout)
9、import 包名
注意:想通过这种方式进行导入,也必须在__init__.py中定义好具体内容。
如果没定义__init.py的内容,则无法引用包中的模块资源,强行引用则导致报错。
那我们配置__init__.py文件的内容如下:
# file: trade/__init__.py
print('我是__init__.py')
version = 1.0
from . import order
from . import pay
# import 包名导入方式 __all__ 不起作用
# __all__ = ('order', 'pay', 'version')
导入测试代码如下:
import trade
print(f'trade包的版本:{trade.version}')
trade.order.create_order()
trade.pay.ali_pay()
以上方式,都可以用于引入子包,只需要在包名后面跟上子包名即可。
在trade包中创建一个子包order_type,其中包含type_a模块,目录结构如下:
└──trade/
└── order_type/ # 子包 order_type
├── __init__.py
└── type_a.py # 支付模块
├── __init__.py
├── order.py # 订单模块
└── pay.py # 支付模块
下面是一个导入并引用子包的简单示例,__init__.py文件为空即可。
type_a模块的内容如下:
def show_info():
print('订单类型A')
type_a在其他python文件中导入示例代码如下:
from trade.order_type.type_a import show_info
show_info()
☞ 由于第三方包相关内容较多且重要,下篇文章详细介绍。