1 模块
1.1 模块的概念
模块就是实现了一定功能的一个组件
一个python文件就是一个模块
创建python文件,就是创建模块
1.2 模块的代码规范
① 模块头部文档注释
模块的作用
模块的开发作者
模块的开发时间
模块的使用注意事项
② 引入操作
引入的系统内建模块
import 模块名称
引入其他模块
import 模块名称
本文为展示需要,部分代码不是在开头引入,实际应用中,正常情况下应该在文件开头引入
③ 全局变量
当前模块中使用到的全局变量声明
④ 函数定义
当前模块中需要的函数声明
⑤ 类型声明定义
1.3 模块引入
1.3.1 绝对引入
绝对引入会从以下绝对路径(固定不变的路径)顺序寻找模块
① 当前文件夹
② 环境变量
③ 解释器环境sys.path
引入语法
# 直接引入
# import 模块
# 引入内置模块string
import string
# 打印小写字母
print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz
# 别名引入,使用时直接使用别名
# import 模块 as 别名
# 引入内置模块time,并起名为t
import time as t
# 获取当前时间戳(1970年01月01日00时00分00秒起至现在的总秒数)
print(t.time()) # 1588491776.6653187
# from方式引入,但一般不这样引入,避免与模块中的变量或函数重名
# from 模块 import 变量/函数/类型
# 从内置模块datetime引入其中的datetime功能
from datetime import datetime
# 获取当前时间
print(datetime.now()) # 2020-05-03 15:46:58.708223
1.3.2 相对引入
相对路径:路径是相对当前文件/模块来确定
. 表示的是当前文件夹
… 表示的是上一级文件夹
…/… 表示上上级文件夹
类似的,相对引入也有三种方式,但要注意使用相对引入时的运行方式,如从当前文件夹引入:
from . import 模块
从当前文件夹引入模块,由于使用了当前文件夹作为相对路径,所以在项目运行的时候需要将文件夹路径带入进入,否则会报错
运行命令(需要在命令行中运行):
python -m 文件夹.模块名
指定运行文件夹中的 python 模块,模块不能带后缀名称
from . import 模块 as 别名
from . 模块 imoprt 变量/函数/类型
使用相对引入,要尽量避免跨文件夹引入,如果真有此情况,优先考虑能否使用绝对引入
1.3.3 模块导入和生效
导入将模时,会自动将模块内代码的执行一遍,且只有第一次导入生效
test.py的内容:
在test2.py中导入test模块(test.py)
运行test2.py,test.py的代码会自动执行一遍
2 包
2.1 包的概念
包就是一个文件夹,用来整理包含相似功能模块,使用方式与模块类似
python中,标准包是包含了一个__init__.py模块的文件夹,__init__.py文件称为包声明文件
2.2 包的引入
2.2.1 绝对引入
绝对引入有以下几种引入方式,一般使用前面两种,导入后使用方法与模块类似:
from 包 import 模块..
from 包 import 模块 as 别名
from 包.模块 import 模块内部变量/函数/类型
import 包
# 该方法需要修改__init__.py文件,作为import内部模块的操作,否则容易出错
from 包 import * # 导入包中所有内容,尽量避免使用
2.2.2 相对引入
类似的模块的相对导入,常用包的导入方法有以下两种:
from .包 import 模块
from .包 import 模块 as 别名
2.3 包的导入和生效
引入包时,会自动执行__init__.py中的代码
3 模块化开发
3.1 功能边界
是模块拆分的一种方式,根据需要有不同拆分依据,如:
根据操作数据角色(如管理员、用户)
根据操作数据不同(如用户数据、商品数据)
根据操作数据方式(业务、视图)
3.2 代码分层
代码分层主要是避免循环引入:
- 上层模块调用下层模块中的函数
- 下层模块中的函数给上层模块返回数据[不能调用]
- 模块不能跨增引入和调用
3.3 模块循环引入可能出现的问题
某些时候,并不能完全按照代码分层的规则,就会出现模块循环引入的情况,可能会出现一些问题:
- 引入不是调用,引入后没有循环调用,不一定会出现问题
- 导入模块后代码会自动执行,循环引入不是必须会出错,但可能存在bug
- 可能会消耗内存,内存溢出程序崩溃
- 可能会导致某个模块失效
解决方法:
- 重新设计代码,但成本较高
- 按需导入:
1)使用from方法导入需要使用的模块 ,避免导入不需要使用的模块
2)只在需要使用的地方导入
4 常用内置模块
4.1 内置模块查询
python内置模块可以在官方文档中查询:
进入https://www.python.org
打开Documentation > Docs 可查询得到
4.2 random模块
import random
# random() 随机产生一个0~1的伪随机数
print(random.random())
# uniform() 产生指定范围的小数
print(random.uniform(1, 5))
# randrange() 随机产生一个包含start不包含end范围之内的整数,左闭右开
print(random.randrange(5, 13))
# randint(start, end) 随机产生一个包含start和end范围之内的整数,左闭右闭
print(random.randint(5, 13))
# choice() 随机从序列中(一般是列表)获取一个数据
lst = [13, 1, 5, 1]
print(random.choice(lst))
# choices(lst, k = n) 随机从序列(一般是列表)中获取多个数据
print(random.choices(lst, k=2))
# shuffle(lst) 随机打乱数据,并返回None, 一般做数据混淆
print(random.shuffle(lst))
print(lst) # 再打印列表顺序已改变
4.3 math模块
用于数学运算的模块,如:
import math
# floor() 向下取整
print(math.floor(5.8)) # 5
# ceil() 向上取整
print(math.floor(5.3)) # 5
# trunc() 截断
print(math.trunc(5.5)) # 5
# 三角函数,默认是弧度,角度要用radians()转换为弧度
print(math.sin(math.radians(45))) # 0.7071067811865476
print(math.cos(math.radians(45))) # 0.7071067811865476
print(math.tan(math.radians(45))) # 0.9999999999999999
4.4 hashlib模块
单向加密算法模块,如:
import hashlib
password = "123456"
password1 = hashlib.md5(password.encode("UTF-8"))
# md5() 单向散列加密算法
# shaxxx() 单向哈希加密算法
print(password1.digest()) # b'\xe1\n\xdc9I\xbaY\xab\xbeV\xe0W\xf2\x0f\x88>'
4.5 string模块
提供系统基本字符串,如:
import string
# 小写字母
print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz
# 大写字母
print(string.ascii_uppercase) # ABCDEFGHIJKLMNOPQRSTUVWXYZ
# 大小写字母
print(string.ascii_letters) # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
# 十进制数字
print(string.digits) # 0123456789
# 十六进制数字
print(string.hexdigits) # 0123456789abcdefABCDEF
# 八进制数字
print(string.octdigits) # 01234567
# 空白符
print(string.whitespace) # ' \t\n\r\x0b\x0c'
# 标点符号
print(string.punctuation) # '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
# 输出上述digits + ascii_letters + punctuation + whitespace
print(string.printable)
4.6 sys模块
import sys
# version 返回解释器版本号
print(sys.version)
# path 返回模块的搜索路径
print(sys.path)
import sys
# argv 接受命令行下的参数
res = sys.argv
path = res[0] # 路径
s1 = res[1] # 参数1
s2 = res[2] # 参数2
if s1 == "pipa" and s2 == "music":
print("今夜闻君琵琶语,如听仙乐耳暂明")
else:
print("窗前明月光,疑是地上霜")
命令行执行python命令,文件名为test.py,输入参数,如果过文件中有其他代码,也会执行:
4.7 time模块
4.7.1 python中的时间表示
- 时间戳(timestamp)
时间戳是计算机能够识别的时间表示的是从1970年1月1日00:00:00开始到现在的秒值
- 时间元组(结构化时间,struct_time)
时间元组用于操作时间,共有9个元素(年,月,日,时,分,秒,一周的第几日,一年中第几天,夏令时)
1) 年 tm_year (4 位数) 2008
2) 月 tm_mon 1到12
3) 日 tm_mday 1到31
4) 小时 tm_hour 0到23
5) 分钟 tm_min 0到59
6) 秒 tm_sec 0到61(60或61是闰秒)
7) 一周的第几日 tm_wday 0到6(0是周一)
8) 一年的第几日 tm_yday 1到366(儒略历)
9) 夏令时tm_isdst -1,0,1,-1是决定是否为夏令时的旗帜
- 格式化时间字符串(formatString)
格式化时间字符串是人能够看懂的时间
常用表示方式:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24 小时制小时数(0-23)
%I 12 小时制小时数(01-12)
%M 分钟数(00-59)
%S 秒(00-59)
4.7.2 time模块时间操作
import time
# 获取当前时间戳
print(time.time())
# 时间戳转换为时间元组(当地时间)
# 默认当前时间
# 参数可传入时间戳
print(time.localtime())
print(time.localtime(1332534657))
# 时间戳转换为时间元组(协调世界时UTC,与北京时间少 8 小时)
print(time.gmtime())
# 时间元组转换为时间戳
print(time.mktime(time.localtime()))
# 时间元组和格式化字符串之间的转换
# 时间元组转换为字符串
# time.strftime(格式定义字符串, 结构化时间字符串)
# 结构化时间参数若不传,则显示当前时间
# 连接符号可以修改为/ - :等
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 2020-05-03 22:40:27
print(time.strftime('%Y-%m-%d', time.localtime(1524232131))) # 2018-04-20
# 字符串转换为时间元组
# time.strptime(时间字符串,字符串对应格式)
print(time.strptime("2020-5-17", "%Y-%m-%d"))
# 时间元组转换为时间串
# 如果不传参数,直接返回当前时间的格式化串
# time.asctime(结构化时间)
print(time.asctime()) # Sun May 3 22:50:16 2020
# 时间戳转换时间串
# 如果不传参数,直接返回当前时间的格式化串
print(time.ctime()) # Sun May 3 22:52:21 2020
4.7.3 time.timesleep()
让程序等待指定时间,单位为秒
import time
# 让程序等待5秒
time.sleep(5)
4.8 datetime模块
datetime当中重新封装了time模块,除有time模块的功能,还提供更多的功能类,如datetime,time,date等
date类部分功能:
from datetime import date
# 返回当前日期
print(date.today()) # 2020-05-04
# 相当于:
# import datetime
# print(datetime.date.today())
# 获取年月日
d1 = date(2020, 6, 17)
print(d1.year) # 2020
print(d1.month) # 6
print(d1.day) # 17
# 一周第几天 0为周一
print(d1.weekday()) # 2
# 返回星期几
print(d1.isoweekday()) # 3
# 获取格式化字符串(固定)
print(d1.isoformat()) # 2020-06-17
# 自定义格式化输出,与time模块的strftime类似
print(d1.strftime("%Y/%m/%d")) # 2020/06/17
time类部分功能:
from datetime import time
# 获取时分秒
t1 = time(22, 15, 20)
print(t1.hour) # 22
print(t1.minute) # 15
print(t1.second) # 20
# 获取格式化字符串(固定)
print(t1.isoformat()) # 22:15:20
# 自定义格式化输出,与time模块的strftime类似
print(t1.strftime("%H-%M-%S")) # 22-15-20
datetime类(date和time的结合)部分功能:
from datetime import datetime
# 获取当前日期时间
t1 = datetime.today()
t2 = datetime.now()
print(t1) # 2020-05-04 10:37:22.436514
print(t2) # 2020-05-04 10:37:22.436514
# 获取年月日时分秒(以t1为例)
t = datetime(2020, 5, 17, 10, 44, 55)
print(t.year) # 2020
print(t.month) # 5
print(t.day) # 17
print(t.hour) # 10
print(t.minute) # 44
print(t.second) # 55
# 只获取日期对象
t3 = t.date()
# 只获取时间对象
t4 = t.time()
# 格式化输出
print(t.strftime("%Y-%m-%d %H:%M:%S")) # 2020-05-17 10-44-55
# 获取格式化字符串(固定)
print(t.isoformat()) # 2020-05-17T10:44:55
# 根据时间戳创建datetime对象
t5 = datetime.fromtimestamp(1672143342)
print(t5.year) # 2022