❝Python入门第二十三课,主要是学习了模块,它是封装代码与命名空间的单元,通过导入复用功能,使项目结构清晰、维护便捷。
概述
❏ 在 Python 中,一个.py文件就是一个模块(Module)。
❏ 模块中可以包含:变量、函数、类等很多内容。
❏ 通常把能够实现某一特定功能的代码,集中放在一个模块中(模块就类似于一个工具箱)。
❏ 模块可以提高代码的『可维护性』和『可复用性』,还可以避免命名冲突。
模块分类
Python 中的模块分为三类,分别是:
- 标准库模块:是指随着安装 Python 时一起安装在我们的电脑上的那些模块。标准库模块保存在
Python安装目录的Lib文件夹中。比如我们之前用过的copy模块。 - 自定义模块:是指程序员自行创建的模块。下文会详细介绍。
- 第三方模块:是指安装的第三方包中的模块。(本文不做介绍,将在下一篇文章《包》中与第三方管理包一起介绍)。
标准库模块
标准库模块是指随着安装 Python 时一起安装在我们的电脑上的那些模块。
标准库模块分为两类:
1、内置模块
有一些标准库模块是用C语言实现的,这些用C语言实现的模块,这些模块被称为内置模块。常用内置模块如下:
- time:时间相关操作(获取时间、延时、格式化时间等)。
2、非内置模块
常用非内置模块如下:
- os:操作系统相关操作(文件、文件夹、路径系统层面的操作)。
- random:随机数相关(生成随机数、随机选择等)。
❝标准库模块保存在Python安装目录中的Lib文件夹中,但内置模块无法在Lib中看到。
对于非内置模块,可以通过模块名.__file__的语法查看模块文件位置。
标准库模块使用示例代码:
# 标准库模块import copyimport randomimport osimport sysimport timeimport math# 查看非内置模块的文件路径print(copy.__file__)print(os.__file__)print(random.__file__)# 强行通过__file__查看内置模块的文件路径,运行时报错:AttributeError: module 'sys' has no attribute '__file__'.# print(sys.__file__)# 以下为标准库模块的基本使用# 创建一个文件夹# os.mkdir('data')# 随机选择一个人names = ['乔丹', '科比', '詹姆斯', '东契奇']print(random.choice(names))# 打乱for i in range(3): random.shuffle(names) print(names)# 休眠# time.sleep(5)print('sleep out')# 获取当前时间print(time.strftime('%Y-%m-%d %H:%M:%S'))print(time.strftime('%p %I:%M:%S'))# 开平方print(math.sqrt(4.0))# 取绝对值print(math.fabs(-4.0))# 获取Python解释器的版本print(sys.version)
创建自定义模块
1、模块命名注意点:
- 不要与标准库模块同名(一旦同名,
Python会优先引入标准库模块)。
2、创建如下文件:
├── order.py # 订单模块└── pay.py # 支付模块
order模块中包含:创建订单、关闭订单,等相关功能。
# 订单最大金额max_order_amount = 10000# 创建订单defcreate_order(): print('订单创建成功!')# 取消订单defcancel_order(): print('订单已被取消!')# 提示信息defshow_info(): print('我是来自【订单】模块的提示!')
pay模块中包含:微信支付、支付宝支付,等相关功能。
# 支付超时时间timeout = 1800# 微信支付defwechat_pay(): print('微信支付成功!')# 支付宝支付defali_pay(): print('支付宝支付成功!')# 提示信息defshow_info(): print('我是来自【支付】模块的提示!')
如何导入模块
Python 中有以下5中导入模块的方式:
1、import 模块名
如下写法,会导入order模块和pay模块的全部内容,又叫全部导入,是最简单的导入方式。
import orderimport payprint(f'订单最大支付金额{order.max_order_amount}')order.create_order()order.cancel_order()order.show_info()print()print(f'支付超时时间{pay.timeout}秒')pay.wechat_pay()pay.ali_pay()pay.show_info()
注意:
- Python 中导入模块的时候,会执行对应模块中的代码。
2、import 模块名 as 别名
import order as oimport pay as pprint(f'订单最大支付金额{o.max_order_amount}')o.create_order()o.cancel_order()o.show_info()print()print(f'支付超时时间{p.timeout}秒')p.wechat_pay()p.ali_pay()p.show_info()
3、from 模块名 import 具体内容1, 具体内容2, ......
from order import max_order_amount, create_orderfrom pay import timeout, wechat_payprint(f'订单最大支付金额{max_order_amount}元')create_order()print(f'订单将在{timeout}秒后自动关闭,请尽快支付!')wechat_pay()
4、from 模块名 import 具体内容 as 别名
from order import max_order_amount as max_amt, create_order as ccfrom pay import timeout as tm, wechat_pay as wxpayprint(f'订单最大支付金额{max_amt}元')cc()print(f'订单将在{tm}秒后自动关闭,请尽快支付!')wxpay()
5、from 模块名 import *
from order import *from pay import *max_order_amount = 999print(f'订单最大金额{max_order_amount}') # 订单最大金额999create_order()cancel_order()show_info() # 我是来自【支付】模块的提示!print(f'订单支付超时时间{timeout}秒')wechat_pay()ali_pay()show_info() # 我是来自【支付】模块的提示!
注意:
- 同名函数或者变量,后面导入的会覆盖前面的导入的,如上面示例代码中的
show_info()函数; - 在导入语句之后,新定义的变量或函数,也会覆盖导入的同名函数或变量,如上面示例代码中的
max_order_amount变量。
__all__ 与 __name__
1、关于**__all__**:
❏ 在 Python 模块中,可通过__all__来控制from 模块 import *允许导入哪些内容。
❏__all__的值可以是:列表、元组。
示例代码:
首先,在模块 order 中设置 __all__,修改后的代码如下:
# 订单最大金额max_order_amount = 10000# 创建订单defcreate_order(): print('订单创建成功!')# 取消订单defcancel_order(): print('订单已被取消!')# 提示信息defshow_info(): print('我是来自【订单】模块的提示!')# 列表语法# __all__ = ['create_order']# 元组语法,注意:元组只有一个元素时一定要写末尾的逗号__all__ = ('create_order',)
然后,下面的代码进行导入测试:
from order import *create_order()# cancel_order() # 运行时报错: name 'cancel_order' is not definedprint(max_order_amount) # 运行时报错:name 'max_order_amount' is not defined
提示:在 PyCharm IDE 中输入测试代码时,如果发现未被允许导入的函数或变量,运行时也可以成功调用,可能是触发了 PyCharm 自动导入了,请查看文件头部的代码,如果有自动导入代码,请删除后重新运行。
2、关于**__name__**:
❏ __name__是每个 Python 模块(.py文件)都拥有的一个内置变量。
❏ 它的具体值取决于模块的运行方式:
- 作为主程序直接运行,
__name__的值是__main__; - 作为模块被导入到其他程序中运行,
__name__的值是模块的文件名(不带.py)。
最简单测试代码,在模块的代码中任意位置增加如下代码,然后查看对比运行结果:
# …… 模块其他代码print(f'__name__ 运行时的值:{__name__}')
介绍一个有意义的引用场景:在模块内通过获取__name__运行时的值,来控制测试代码运行逻辑,来进行方便测试。具体代码实现如下,还是以order模块为例:
# 订单最大金额max_order_amount = 10000# 创建订单defcreate_order(): print('订单创建成功!')# 取消订单defcancel_order(): print('订单已被取消!')# 提示信息defshow_info(): print('我是来自【订单】模块的提示!')# 列表语法# __all__ = ['create_order']# 元组语法,注意:元组只有一个元素时一定要写末尾的逗号__all__ = ('create_order',)print(f'__name__ 运行时的值:{__name__}')# 只有当前模块作为主程序运行时,才执行下面的代码;而被导入场景则不会运行if __name__ == '__main__': print(f'当前订单允许的最大金额:{max_order_amount}') create_order() cancel_order()