❝Python入门第二十四课,主要是学习了包,包通过分层组织模块管理命名空间,自定义包能将相关功能归类,构建清晰、可扩展的项目结构。
概述
❏ 包是一种组织模块的方式,包中可以包含:各种模块、子包、其他资源等。
❏ 在Python中,『包含__init__.py的文件夹』就是一个包(Package)。
❏ 通常会把『某个特定功能相关的所有模块』放入一个包中。
❏ 使用包可以进一步提升代码的:可维护性、可复用性,便于管理大型项目。
包与模块的关系
❏ 一个模块就是一个.py文件,包是用来“管理模块”的目录(文件夹)。
❏ 一个包可以有多个模块,也可以有多个子包。
包的分类
Python中的包分为三类:
就是指随着安装 Python 时一起安装在我们的电脑上的那些包,存放在 Python 安装目录下的Lib目录下,可直接导入使用,更多信息请阅读官方文档。下面是一个标准库包的使用示例:
from collections import Counterscores = [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# 创建订单defcreate_order(): print('订单创建成功!')# 取消订单defcancel_order(): print('订单已被取消!')# 提示信息defshow_info(): print('我是来自【订单】模块的提示!')
# file: trade/pay.py# 支付超时时间timeout = 1800# 微信支付defwechat_pay(): print('微信支付成功!')# 支付宝支付defali_pay(): print('支付宝支付成功!')# 提示信息defshow_info(): print('我是来自【支付】模块的提示!')
了解__init__.py文件
❏ __init__.py是包的初始化文件,在包被导入时, __init__.py会被自动调用。
❏ __init__.py中可以编写一些包的初始化逻辑。
❏ __init__.py中所定义的内容,会被from 包名 import *的形式全部引入。
❏ __init__.py中也可以使用__all__来控制包中的哪些模块可以被from 包名 import *引入。
导入包的9种方式
1、import 包名.模块名
import trade.orderimport trade.paytrade.order.create_order()trade.pay.wechat_pay()
2、import 包名.模块名 as 别名
import trade.order as oimport trade.pay as po.create_order()p.wechat_pay()
3、from 包名.模块名 import 具体内容
from trade.order import max_order_amount, create_orderfrom trade.pay import timeout, wechat_payprint('最大订单金额:' + 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_orderfrom trade.pay import timeout as tm_out, wechat_pay as wxpayprint('最大订单金额限制:' + str(max_amt))c_order()tm_out = 5print('订单支付时限:' + 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, payorder.create_order()pay.wechat_pay()
7、from 包名 import 模块名 as 别名
from trade import order as o, pay as po.create_order()p.wechat_pay()
8、from 包名 import *
注意:想通过这种方式进行导入,就必须在__init__.py中定义好具体内容。
如果没定义__init.py的内容,则无法引用包中的模块资源,强行引用则导致报错。
那我们配置__init__.py文件的内容如下:
# file: trade/__init__.pyprint('我是__init__.py')version = 1.0from . import orderfrom . 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__.pyprint('我是__init__.py')version = 1.0from . import orderfrom . import pay# import 包名导入方式 __all__ 不起作用# __all__ = ('order', 'pay', 'version')
导入测试代码如下:
import tradeprint(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模块的内容如下:
defshow_info(): print('订单类型A')
type_a在其他python文件中导入示例代码如下:
from trade.order_type.type_a import show_infoshow_info()
☞ 由于第三方包相关内容较多且重要,下篇文章详细介绍。