文章目录
1. time模块
(1)功能汇总
在Python中,通常有这3种方式来表示时间:
时间戳(timestamp)
:通常来说,时间戳表示的是从1970年1月1日00:00:00开始
按秒计算的偏移量
.我们运行“type(time.time())”,返回的是float类型。
通常用于时间间隔的计算
。
格式化的时间字符串
(Format String)(按照某种格式显示的)例如‘1999-12-06’。通常用于
格式化显示时间
。
符号 说明 %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) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %X 本地相应的时间表示 %Z 当前时区的名称 %% %号本身
结构化时间(struct_time)
:struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
索引(Index) 属性(Attribute) 值(Values) 0 tm_year(年) 比如2011 1 tm_mon(月) 1 – 12 2 tm_mday(日) 1 – 31 3 tm_hour(时) 0 – 23 4 tm_min(分) 0 – 59 5 tm_sec(秒) 0 – 60 6 tm_wday(weekday) 0 – 6(0表示周一) 7 tm_yday(一年中的第几天) 1 – 366 8 tm_isdst(是否是夏令时) 默认为0
(2)程序解释
- 3种类型的时间举例
import time
print('--------------时间戳-------------')
time1 = time.time() #时间戳,float类型
time2 = time.time()
diff_time = time2 - time1
print('时间间隔:{0} s'.format(diff_time))
print('--------------时间字符串-------------')
str1 = time.strftime("%Y-%m-%d %X")
print(str1)
print('--------------结构化时间(struct_time) -------------')
loc_time_1 = time.localtime()#本地时区的struct_time
loc_time_2 = time.gmtime() #UTC时区的struct_time
print(loc_time_1)
print(loc_time_2)
输出:
--------------时间戳-------------
时间间隔:4.76837158203125e-07 s
--------------时间字符串-------------
2021-11-13 22:29:37
--------------结构化时间(struct_time) -------------
time.struct_time(tm_year=2021, tm_mon=11, tm_mday=13, tm_hour=22, tm_min=29, tm_sec=37, tm_wday=5, tm_yday=317, tm_isdst=0)
time.struct_time(tm_year=2021, tm_mon=11, tm_mday=13, tm_hour=14, tm_min=29, tm_sec=37, tm_wday=5, tm_yday=317, tm_isdst=0)
- 3种类型的时间转换
import time
print('--------------时间戳《==》时间字符串-------------')
t = time.time()
st = time.localtime(t) #时间戳 ---> 结构化时间
ft = time.strftime('%Y/%m/%d %H:%M:%S',st) # 结构化时间 ---> 格式化时间
print(st)
print(ft)
print('--------------结构化时间(struct_time)《==》时间字符串 -------------')
st = time.strftime('%Y/%m/%d %H:%M:%S')
ft = time.strptime(st,'%Y/%m/%d %H:%M:%S') # 时间字符串 ---> 格式化时间
st= time.strftime('%Y/%m/%d %H:%M:%S',ft) # 格式化时间 ---> 时间字符串
print(st)
print(ft)
输出:
--------------时间戳《==》时间字符串-------------
time.struct_time(tm_year=2021, tm_mon=11, tm_mday=13, tm_hour=22, tm_min=45, tm_sec=50, tm_wday=5, tm_yday=317, tm_isdst=0)
2021/11/13 22:45:50
--------------结构化时间(struct_time)《==》时间字符串 -------------
2021/11/13 22:45:50
time.struct_time(tm_year=2021, tm_mon=11, tm_mday=13, tm_hour=22, tm_min=45, tm_sec=50, tm_wday=5, tm_yday=317, tm_isdst=-1)
import time
print('--------------时间戳》》时间字符串-------------')
#time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串
time1 = time.time() #时间戳,float类型
str_time = time.ctime(time1)
print(str_time)
print('--------------结构化时间(struct_time)》》时间字符串 -------------')
#time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串
loc_time = time.localtime()#本地时区的struct_time
print(time.asctime(loc_time))
输出:
--------------时间戳》》时间字符串-------------
Sat Nov 13 22:36:19 2021
--------------结构化时间(struct_time)》》时间字符串 -------------
Sat Nov 13 22:36:19 2021
2. datetime模块
(1)功能汇总
datetime模块中包含如下类:
类名 | 功能说明 |
---|---|
date | 日期对象,常用的属性有year, month, day |
time | 时间对象 |
datetime | 日期时间对象,常用的属性有hour, minute, second, microsecond |
datetime_CAPI | 日期时间对象C语言接口 |
timedelta | 时间间隔,即两个时间点之间的长度 |
tzinfo | 时区信息对象 |
datetime模块中包含的常量:
常量 | 功能说明 | 用法 | 返回值 |
---|---|---|---|
MAXYEAR | 返回能表示的最大年份 | datetime.MAXYEAR | 9999 |
MINYEAR | 返回能表示的最小年份 | datetime.MINYEAR | 1 |
(2)程序解释
import datetime
now_time = datetime.datetime.now() # 现在的时间
# 只能调整的字段:weeks days hours minutes seconds
print(datetime.datetime.now() + datetime.timedelta(weeks=3)) # 三周后
print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) # 三周前
print(datetime.datetime.now() + datetime.timedelta(days=-3)) # 三天前
print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
print(datetime.datetime.now() + datetime.timedelta(hours=5)) # 5小时后
print(datetime.datetime.now() + datetime.timedelta(hours=-5)) # 5小时前
print(datetime.datetime.now() + datetime.timedelta(minutes=-15)) # 15分钟前
print(datetime.datetime.now() + datetime.timedelta(minutes=15)) # 15分钟后
print(datetime.datetime.now() + datetime.timedelta(seconds=-70)) # 70秒前
print(datetime.datetime.now() + datetime.timedelta(seconds=70)) # 70秒后
current_time = datetime.datetime.now()
# 可直接调整到指定的 年 月 日 时 分 秒 等
print(current_time.replace(year=1977)) # 直接调整到1977年
print(current_time.replace(month=1)) # 直接调整到1月份
print(current_time.replace(year=1989,month=4,day=25)) # 1989-04-25 18:49:05.898601
# 将时间戳转化成时间
print(datetime.date.fromtimestamp(1232132131)) # 2009-01-17
print(datetime.date.today()) #2021-11-13
3. calendar模块
(1)功能汇总
calendar.calendar(year,w=2,l=1,c=6,m=3)
,返回一个字符串格式的年历。
- year接收一个年份数字,可以是过去现在或未来,比如我这里打印的是1千年以后的3019年。
- w表示个位天数相邻两天之间的间隔宽度(字符空格数),默认是2.
- l表示每一个周占用的行数,默认是1。
- c表示并排的两个月之间的间隔宽度,默认是6。但是c不小于w。即当c值小于w时,c等于w。
- m表示并排展示多少个月。默认是3,显示一排3个月,会显示4排。
calendar.prcal(year,w=2,l=1,c=6, m=3)
也是打印一年的年历,相当于print(calendar.calendar(year,w,l,c))。
calendar.month(2019, 10, w=0, l=0)
,打印某一个月的日历。
calendar.timegm(tupletime)
接受一个时间元组,返回时间戳,时间元组的值依次表示年、月、日、时、分、秒。
calendar.weekday(year,month,day)
返回传入的日期是星期几。
calendar.isleap(year)
返回传入的年是不是闰年,是返回True,否则为false。如2020年是闰年。
calendar.leapdays(start, end)
返回start,end之间有多少个闰年,左闭右开区间。
(2)程序解释
import calendar
print("month: \n", calendar.month(2019, 10, w=0, l=0))
#print("month: \n", calendar.prmonth(2019, 10, w=0, l=0))
print("monthcalendar: ", calendar.monthcalendar(2019, 11))#2019年11月的日历
print("monthrange: ", calendar.monthrange(2019, 10))#2019年11月日历的范围
输出:
month:
October 2019
Mo Tu We Th Fr Sa Su
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
monthcalendar: [[0, 0, 0, 0, 1, 2, 3], [4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 0]]
monthrange: (1, 31)
4. sys模块
Python的sys模块提供访问由解释器
使用或维护的变量的接口
,并提供了一些函数用来和解释器进行交互,操控Python的运行时环境。
(1)功能汇总
方法 | 说明 |
---|---|
|
传递给程序的
|
|
模块的搜索路径;
表示当前脚本所在目录 |
|
通过引发SystemExit异常来退出当前程序。n为0表示正常,非零表示异常。 |
sys.modules | 已加载的模块的字典 |
sys.exc_info() | 获取正在处理的异常的相关信息 |
sys.builtin_module_names | 当前解释器所有内置模块的名称 |
sys.copyright | 包含解释器版权相关信息的字符串 |
sys.exec_prefix | 用于查找特定于当前机器的python库的路径前缀 |
|
Python解释器可执行文件的绝对路径 |
sys.float_info | 包含有关浮点数实现的信息的结构序列 |
sys.float_repr_style | 表示浮点数的repr()方法的输出样式的字符串 |
sys.hash_info | 包含哈希算法相关信息的结构序列 |
sys.hexversion | 对sys.version_info中包含的版本信息进行编码后使用十六进制表示的整数 |
sys.implementation | 包含有关Python实现的相关信息 |
sys.int_info | 包含有关整形实现的信息的结构序列 |
sys.maxsize | 返回字符串、列表、字典和其他内置类型的最大长度 |
sys.maxunicode | 返回能够表示的最大Unicode码点的整数值 |
|
返回平台标识符字符串 |
sys.prefix | 返回安装平台无关Python文件的目录 |
sys.thread_info | 包含有关线程实现的信息的结构序列 |
|
表示当前解释器版本的字符串 |
sys.version_info | 当前解释器版本的命名元组 |
sys.byteorder | 本机的字节排序方式,little表示小尾,big表示大尾 |
sys.api_version | 返回表示Python解释器的C语言版本API的整数 |
|
获取对象占用的内存大小(
) |
(2)程序解释
- sys.argv
传递给程序的命令行参数列表,其中argv[0]是传入的脚本名字,其它为传入的参数名字,且为str类型。
import sys
# filename:sys_test.py
for i in range(len(sys.argv)):
print('argv{0}: type is {1}, value is {2}'.format(i, type(sys.argv[i]), sys.argv[i]))
然后执行代码
python argv_test.py 1 a 2 b
。运行结果如下:
argv0: type is <class 'str'>, value is sys_test.py
argv1: type is <class 'str'>, value is 1
argv2: type is <class 'str'>, value is a
argv3: type is <class 'str'>, value is 2
argv4: type is <class 'str'>, value is b
- sys.path
表示模块的
搜索路径
,其中sys.path[0]表示
脚本当前目录
。
import sys
print(sys.path[0])
输出:
/home/xxx/workspace/python/python_tutorials
- sys.getsizeof()
获取对象占用的内存大小(用字节表示)
import sys
for obj in [int(), float(), list(), tuple(), set(), dict(), object]:
print(str(obj.__class__).ljust(20), sys.getsizeof(obj))
输出:
<class 'int'> 24
<class 'float'> 24
<class 'list'> 56
<class 'tuple'> 40
<class 'set'> 216
<class 'dict'> 232
<class 'type'> 408
5. os模块
os模块是与操作系统交互的一个接口。
(1)功能汇总
方法 | 说明 |
---|---|
|
获取当前工作目录,Current working directory |
|
改变当前脚本工作目录;相当于shell下cd |
|
返回
|
os.pardir |
获取当前目录的
|
|
可生成多层递归目录 |
|
若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 |
|
生成单级目录;相当于shell中mkdir dirname |
|
删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname |
os.listdir(‘dirname’) |
列出指定目录下的所有文件和子目录,包括隐藏文件,并以
方式打印。它不包括 . 和 … 即使它在文件夹中。 |
|
删除一个文件 |
|
重命名文件/目录 |
os.stat(‘path/filename’) | 获取文件/目录信息 |
|
输出操作系统特定的路径分隔符,win下为”\“,Linux下为”/” |
os.linesep | 输出当前平台使用的行终止符,win下为”\t\n”,Linux下为”\n” |
os.pathsep | 输出用于分割文件路径的字符串 win下为;,Linux下为: |
|
输出字符串指示当前使用平台。win->‘nt’; Linux->‘posix’ |
|
运行shell命令,直接显示 |
os.environ | 获取系统环境变量 |
os.path.abspath(path) | 返回path规范化的绝对路径 |
os.path.split(path) |
将path分割成目录和文件名
|
os.path.join() |
|
os.path.dirname(path) | 返回path的目录。其实就是os.path.split(path)的第一个元素 |
os.path.basename(path) | 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 |
|
path是否存在,可以是
路径 |
|
如果path是绝对路径,返回True |
|
如果path是一个存在的
,返回True。否则返回False |
|
如果path是一个存在的
,则返回True。否则返回False |
|
将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 |
os.path.getatime(path) | 返回path所指向的文件或者目录的最后存取时间 |
os.path.getmtime(path) | 返回path所指向的文件或者目录的最后修改时间 |
|
返回path(文件或文件夹)的大小,字节 |
(2)程序解释
- 进入空间操作
import os
print(os.getcwd()) #当前工作目录
os.chdir('..') #返回上一层目录
print(os.curdir) #当前目录
print(os.getcwd())#当前工作目录
print(os.pardir)#当前目录的上一层
输出:
/home/liqiang/workspace/python/python_tutorials
.
/home/liqiang/workspace/python
..
(3)一些功能备份
- 去掉隐藏文件
list_dir = [f for f in os.listdir(cwd) if not f.startswith(('.'))]
6. pathlib模块
pathlib 库从 python3.4 开始,到 python3.6 已经比较成熟。如果你的新项目可以直接用 3.6 以上,建议用 pathlib。相比于老式的 os.path 有几个优势:
- 老的路径操作函数管理比较混乱,
有的是导入 os, 有的又是在 os.path
当中,而新的用法统一可以用 pathlib 管理。- 老用法在处理不同操作系统 win,mac 以及 linux 之间很吃力。换了操作系统常常要改代码,还经常需要进行一些额外操作。
老用法主要是函数形式,返回的数据类型通常是字符串
。
但是路径和字符串并不等价
,所以在使用 os 操作路径的时候常常还要引入其他类库协助操作。新用法是面向对象,处理起来更灵活方便。- pathlib 简化了很多操作,用起来更轻松。
有两大类一个是纯路径不带I/0操作,另一个可以进行I/0的类。pathlib各个类的继承关系如下图:
(1)功能汇总
Path获得的路径为对象类型,
可以使用str方法转化为字符串。同样可以使用Path()方法将字符串转化path对象
。
下面假设:
- file = Path(‘archive/demo.txt’)
方法 | 说明 |
---|---|
pathlib.Path.cwd() | 获得当前路径 |
pathlib.Path.home() | 获得home目录 |
file.state().st_size | 获得文件大小 |
file.stat().st_ctime | 文件创建时间 |
file.stat().st_mtime | 文件修改时间 |
file.name | 文件名,包含后缀名,如果是目录则获取目录名。 |
file.stem | 文件名,不包含后缀。 |
file.suffix | 后缀,比如 .txt, .png |
p.suffixs | 路径的所有后缀 |
file.parent | 父级目录,相当于 cd … |
p.parents | 所有父目录 |
file.anchor | 锚,目录前面的部分 C:\ 或者 /。 |
file.resolve() | 获得绝对路径 |
dir_path.iterdir() | 可以扫描某个目录下的所有路径(文件和子目录), 打印的会是处理过的绝对路径。 |
dir_path.glob(‘*.txt’) | 匹配路径下的所有.txt文件 |
file.match(‘*.txt’) | 检查路径是否符合规则 |
Path.home() / ‘dir’ / ‘file.txt’ | 可以使用/方法拼接路径,同Path.home().joinpath(‘dir’, ‘file.txt’) |
file.is_file() | 检查路径是否为文件 |
file.is_dir() | 检查路径是否为目录 |
file.exists | 检查路径是否存在 |
path.mkdir() |
|
path.mkdir(parents=True) | 创建多级目录 |
path.rmdir() | 删除目录 |
path.unlink | 删除文件 |
txt_path.replace(‘new_demo.txt’) | 移动文件,txt_path目录下的 demo.txt 文件移动到当前工作目录,并重命名为 new_demo.txt。如果移动的目录不存在,则会报错,可以使用exists方法查询是否存在。 |
txt_path.with_name(‘new.txt’) | 重命名文件 |
txt_path.with_suffix(‘.json’) | 修改文件后缀名 |
常用的 pathlib 和 os 对比图:
操作 | os and os.path | pathlib |
---|---|---|
绝对路径 | os.path.abspath | Path.resolve |
修改权限 | os.chmod | Path.chmod |
创建目录 | os.mkdir | Path.mkdir |
重命名 | os.rename | Path.rename |
移动 | os.replace | Path.replace |
删除目录 | os.rmdir | Path.rmdir |
删除文件 | os.remove, os.unlink | Path.unlink |
工作目录 | os.getcwd | Path.cwd |
是否存在 | os.path.exists | Path.exists |
用户目录 | os.path.expanduser | Path.expanduser and Path.home |
是否为目录 | os.path.isdir | Path.is_dir |
是否为文件 | os.path.isfile | Path.is_file |
是否为连接 | os.path.islink | Path.is_symlink |
文件属性 | os.stat | Path.stat, Path.owner, Path.group |
是否为绝对路径 | os.path.isabs | PurePath.is_absolute |
路径拼接 | os.path.join | PurePath.joinpath |
文件名 | os.path.basename | PurePath.name |
上级目录 | os.path.dirname | PurePath.parent |
同名文件 | os.path.samefile | Path.samefile |
后缀 | os.path.splitext | PurePath.suffix |
(2)程序解释
from pathlib import Path
#获取当前路径
v = Path.cwd()
# 创建 project/test目录
Path('project/test').mkdir(parents=True, exist_ok=True)
# 将test.txt 重命名为 project/tests.txt
Path('test.txt').rename('project/test.txt')
# 拼接目录
paths = ["test","test.txt"]
Path.cwd().parent.joinpath(*paths)
# 获取上上层目录
print(Path.cwd().parent.parent)
#迭代器访问的所有文件、文件夹路径的迭代器
p = Path.cwd()
for i in p.iterdir():
print(i) #i为Path类型,linux下为pathlib.PosixPath类型
#*******************其它操作*************************
path = Path.cwd()
path.parents # 返回所有上级目录的列表
path.parts # 分割路径 类似os.path.split(), 不过返回元组
path.root # 返回路径的根目录
path.is_dir() # 判断是否是目录
path.is_dir() # 是否是文件
path.exists() # 判断路径是否存在
path.open() # 打开文件(支持with)
path.resolve() # 返回绝对路径
path.cwd() # 返回当前目录
path.iterdir() # 遍历目录的子目录或者文件
path.mkdir() # 创建目录
path.rename() # 重命名路径
path.unlink() # 删除文件或目录(目录非空触发异常)
path.joinpath() # 拼接路径
7. shutil模块
shutil模块提供了许多关于
文件和文件集合的高级操作,特别提供了支持文件复制和删除
的功能。
(1)功能汇总
方法 | 说明 |
---|---|
|
将fsrc
至fdst文件,length为fsrc每次读取的长度,用做缓冲区大小 |
|
将src
复制至dst文件,如果dst没有则创建一份 |
copymode(src, dst) | 将src文件权限复制至dst文件。文件内容,所有者和组不受影响 |
copystat(src, dst) | 将权限,上次访问时间,上次修改时间以及src的标志复制到dst。文件内容,所有者和组不受影响 |
|
将文件src复制至dst。dst可以是个目录,会在该目录下创建与src同名的文件,若该目录下存在同名文件,将会报错提示已经存在同名文件。权限会被一并复制。
|
|
将文件src复制至dst。dst可以是个目录,会在该目录下创建与src同名的文件,若该目录下存在同名文件,将会报错提示已经存在同名文件。权限、上次访问时间、上次修改时间和src的标志会一并复制至dst。
|
|
忽略模式,用于配合copytree()方法,传递文件将会被忽略,不会被拷贝 |
|
拷贝文档树,
拷贝至dst文件夹 |
|
移除文档树,将文件夹目录删除,
|
|
将src移动至dst目录下。若dst目录不存在,则效果等同于src改名为dst。若dst目录存在,将会把src文件夹的所有内容移动至该目录下面 |
disk_usage(path) | 获取当前目录所在硬盘使用情况。 |
chown(path, user=None, group=None) | 修改路径指向的文件或文件夹的所有者或分组。 |
which(cmd, mode=os.F_OK | os.X_OK, path=None) |
make_archive(base_name, format, root_dir, …) | 生成压缩文件 |
get_archive_formats() | 获取支持的压缩文件格式。目前支持的有:tar、zip、gztar、bztar。在Python3还多支持一种格式xztar |
unpack_archive(filename, extract_dir=None, format=None) | 解压操作。 |
get_unpack_formats() | 获取支持的解压文件格式。目前支持的有:tar、zip、gztar、bztar和xztar。Python3新增方法 |
(2)程序解释
- copyfileobj
import shutil
f1 = open("file.txt","r")#内容:11
f2 = open("file_copy.txt","a+") #内容:22,追加的方式读写
shutil.copyfileobj(f1,f2,length=1024) # f2变为:2211
- copyfile
import shutil
shutil.copyfile("file.txt","file_copy_1.txt")#会生成一个新的文件file_copy_1.txt
- copytree
将aaa中的所有内容,复制到bbb/ccc中(如果不存在,则自动创建)
import shutil,os
folder1 = os.path.join(os.getcwd(),"aaa")
folder2 = os.path.join(os.getcwd(),"bbb","ccc")# bbb与ccc文件夹都可以不存在,会自动创建
print(folder1)
print(folder2)
# 将"abc.txt","bcd.txt"忽略,不复制
shutil.copytree(folder1,folder2,ignore=shutil.ignore_patterns("abc.txt","bcd.txt"))
- rmtree
删除的文件树必须存在
import shutil,os
folder1 = os.path.join(os.getcwd(),"aaa")
shutil.rmtree(folder1)
8. random模块
random模块用于生成随机数
(1)功能汇总
方法 | 说明 |
---|---|
random.random() |
0,1之间时间生成的
|
random.randint(1,10) |
产生 1 到 10 的一个
|
random.uniform(1.1,5.4) |
产生 1.1 到 5.4 之间的
|
random.randrange(1,100,2) |
生成从1到100的间隔为2的随机整数,
|
random.choice(‘tomorrow’) | 从序列中随机选取一个元素 |
random.choice([‘剪刀’, ‘石头’, ‘布’]) | 随机选择元素 |
random.sample(‘zyxwvutsrqponmlkjihgfedcba’,5) | 随机选择5个元素,生成一个新的列表 |
random.shuffle(items) | 对items打乱排序 |
(2)程序解释
import random
print( random.randint(1,10) ) # 产生 1 到 10 的一个整数型随机数
print( random.random() ) # 产生 0 到 1 之间的随机浮点数
print( random.uniform(1.1,5.4) ) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数
print( random.choice('tomorrow') ) # 从序列中随机选取一个元素
print(random.choice(['剪刀', '石头', '布'])) #随机选择元素
print( random.randrange(1,100,2) ) # 生成从1到100的间隔为2的随机整数,不包括100
print(random.sample('zyxwvutsrqponmlkjihgfedcba',5)) #随机选择5个元素,生成一个新的列表
#打乱排序
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
random.shuffle(items)
print(items) # [4, 3, 8, 2, 5, 9, 6, 1, 0, 7]
9. json模块
JSON (JavaScript Object Notation) 是一种
轻量级的数据交换格式
。Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它主要提供了
四个方法: dumps、dump、loads、load
。
- dump和dumps对python对象进行序列化。将一个Python对象进行JSON格式的编码。
- load和loads反序列化方法,将json格式数据解码为python对象。
python 原始类型向 json 类型的
转化对照表
:
Python | JSON |
---|---|
dict | object |
list, tuple | array |
str, unicode | string |
int, long, float | number |
True | true |
False | false |
None | null |
(1)功能汇总
方法 | 说明 |
---|---|
json.dumps | 将 Python 对象编码成 JSON 字符串 |
json.loads | 将已编码的 JSON 字符串解码为 Python 对象 |
函数以及参数说明:
- dump和dumps介绍:
- dump函数形式:
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
- dumps函数形式:
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
参数 说明 obj 表示是要
序列化的对象
。fp
dump与dumps的唯一区别,dumps没有该参数
,文件描述符,将序列化的str保存到文件中。json模块总是生成str对象,而不是字节对象;因此,fp.write()必须支持str输入。skipkeys 默认为False,如果skipkeysTrue,(默认值:False),则将跳过不是基本类型(str,int,float,bool,None)的dict键,不会引发TypeError。 ensure_ascii 默认值为True,能将所有传入的非ASCII字符转义输出。如果ensure_ascii为False,则这些字符将按原样输出。 check_circular 默认值为True,如果check_circular为False,则将跳过对容器类型的循环引用检查,循环引用将导致OverflowError。 allow_nan 默认值为True,如果allow_nan为False,则严格遵守JSON规范,序列化超出范围的浮点值(nan,inf,-inf)会引发ValueError。 如果allow_nan为True,则将使用它们的JavaScript等效项(NaN,Infinity,-Infinity)。 indent 设置缩进格式,默认值为None,选择的是最紧凑的表示。如果indent是非负整数或字符串,那么JSON数组元素和对象成员将使用该缩进级别进行输入;indent为0,负数或“”仅插入换行符;indent使用正整数缩进多个空格;如果indent是一个字符串(例如“\t”),则该字符串用于缩进每个级别。 separators 去除分隔符后面的空格,默认值为None,如果指定,则分隔符应为(item_separator,key_separator)元组。如果缩进为None,则默认为(’,’,’:’);要获得最紧凑的JSON表示,可以指定(’,’,’:’)以消除空格。 default 默认值为None,如果指定,则default应该是为无法以其他方式序列化的对象调用的函数。它应返回对象的JSON可编码版本或引发TypeError。如果未指定,则引发TypeError。 sort_keys 默认值为False,如果sort_keys为True,则字典的输出将按键值排序。
- load与loads介绍
- load函数形式:
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
参数 说明 fp 文件描述符,将fp(.read()支持包含JSON文档的文本文件或二进制文件)反序列化为Python对象。 object_hook 默认值为None,object_hook是一个可选函数,此功能可用于实现自定义解码器。指定一个函数,该函数负责把反序列化后的基本类型对象转换成自定义类型的对象。 parse_float 默认值为None,如果指定了parse_float,用来对JSON float字符串进行解码,这可用于为JSON浮点数使用另一种数据类型或解析器。 parse_int 默认值为None,如果指定了parse_int,用来对JSON int字符串进行解码,这可以用于为JSON整数使用另一种数据类型或解析器。 parse_constant 默认值为None,如果指定了parse_constant,对-Infinity,Infinity,NaN字符串进行调用。如果遇到了无效的JSON符号,会引发异常。
- loads函数形式:
json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
参数 说明 s 将s(包含JSON文档的str,bytes或bytearray实例)反序列化为Python对象。 encoding 指定一个编码的格式。
loads也不需要文件描述符,其他参数的含义和load函数的一致
。
(2)程序解释
dump和dumps
import json
# dumps可以格式化所有的基本数据类型为字符串
data1 = json.dumps([1,2,3,4]) # 列表
print(data1, type(data1))
data2 = json.dumps(100) # 数字
print(data2, type(data2))
data3 = json.dumps('qlee') # 字符串
print(data3, type(data3))
dict = {"name": "Tom", "age": 23} # 字典
data4 = json.dumps(dict)
print(data4, type(data4))
with open("test.json", "w", encoding='utf-8') as f:
# indent,表示空格数,默认为None,小于0为零个空格
f.write(json.dumps(dict, indent=4)) #保存到f中
#json.dump(dict, f, indent=4) # 保存到f中
输出:
[1, 2, 3, 4] <class 'str'>
100 <class 'str'>
"qlee" <class 'str'>
{"name": "Tom", "age": 23} <class 'str'>
最后保存的test.json内容为:
{
"name": "Tom",
"age": 23
}
import json
dict = '{"name": "Tom", "age": 23}' # 将字符串还原为dict
data1 = json.loads(dict)
print(data1, type(data1))
with open("test.json", "r", encoding='utf-8') as f:
data2 = json.loads(f.read()) # 加载方式一:load的传入参数为字符串类型
print(data2, type(data2))
f.seek(0) # 将文件游标移动到文件开头位置
data3 = json.load(f)# 加载方式二
print(data3, type(data3))
输出:
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
10. pickle模块
pickle模块实现了用于序列化和反序列化Python对象结构的
二进制协议
。pickle模块只能在Python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,pickle序列化后的数据,可读性差,人一般无法识别。
pickle协议和JSON(JavaScript Object Notation)的区别 :
JSON是一种文本序列化格式
(它输出unicode文本,虽然大部分时间它被编码utf-8),而
pickle是二进制序列化格式
;
JSON是人类可读的,而pickle则不是
;- JSON是可互操作的,并且在Python生态系统之外广泛使用,而
pickle是特定于Python的
;
(1)功能汇总
方法 | 说明 |
---|---|
pickle.dump(obj, file, protocol=None,*,fix_imports=True) | 将序列化后的对象obj以二进制形式写入文件file中,效等同于Pickler(file, protocol).dump(obj) |
pickle.dumps(obj, protocol=None,*,fix_imports=True) | pickle.dumps()方法不需要写入文件中,它是直接返回一个序列化的bytes对象。 |
pickle.Pickler(file, protocol=None,*,fix_imports=True) | 实现的功能跟 pickle.dump() 是一样的。 |
pickle.load(file, *,fix_imports=True, encoding=”ASCII”. errors=”strict”) | 将序列化的对象从文件file中读取出来。它的功能等同于 Unpickler(file).load()。 |
pickle.loads(bytes_object, *,fix_imports=True, encoding=”ASCII”. errors=”strict”) | pickle.loads()方法是直接从bytes对象中读取序列化的信息,而非从文件中读取。 |
pickle.Unpickler(file, *,fix_imports=True, encoding=“ASCII”. errors=“strict”) | Unpickler(file).load() 实现的功能跟 pickle.load() 是一样的。 |
(2)程序解释
import pickle
path = 'test' #保存路径
f = open(path, 'wb')
data = {'a':123, 'b':'ads', 'c':[[1,2],[3,4]]}
pickle.dump(data, f) #保存
f.close()
f1 = open(path, 'rb')
data1 = pickle.load(f1) #解析
print(data1)
输出:
{'a': 123, 'b': 'ads', 'c': [[1, 2], [3, 4]]}
11. logging模块
logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:
- 可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
- print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;
(1)基本使用
只有级别大于或等于日志记录器指定级别的日志记录才会被输出,小于该级别的日志记录将会被丢弃
。级别排序:CRITICAL > ERROR > WARNING > INFO > DEBUG。
import logging
#logging的级别为DEBUG,所以全部输出
logging.basicConfig(level = logging.DEBUG,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
输出:
2021-11-14 16:42:56,718 - root - DEBUG - debug message
2021-11-14 16:42:56,718 - root - INFO - info message
2021-11-14 16:42:56,718 - root - WARNING - warning message
2021-11-14 16:42:56,718 - root - ERROR - error message
2021-11-14 16:42:56,718 - root - CRITICAL - critical message
我们将logger的级别改为ERROR,再观察一下输出结果:
2021-11-14 16:44:33,998 - root - ERROR - error message
2021-11-14 16:44:33,998 - root - CRITICAL - critical message
logging.basicConfig函数各参数说明:
参数 说明 filename 指定日志文件名; filemode 和file函数意义相同,指定日志文件的打开模式,‘w’或者’a’; format 指定输出的格式和内容,format可以输出很多有用的信息 datefmt 指定时间格式,同time.strftime(); level 设置日志级别,默认为logging.WARNNING; stream 指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到sys.stderr,当stream和filename同时指定时,stream被忽略. format中输出的格式个内容:
>参数 说明 %(levelno)s 打印日志级别的数值 %(levelname)s 打印日志级别的名称 %(pathname)s 打印当前执行程序的路径,其实就是sys.argv[0] %(filename)s 打印当前执行程序名 %(funcName)s 打印日志的当前函数 %(lineno)d 打印日志的当前行号 %(asctime)s 打印日志的时间 %(thread)d 打印线程ID %(threadName)s 打印线程名称 %(process)d 打印进程ID %(message)s 打印日志信息
(2)将日志输出到文件
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level = logging.DEBUG)
handler = logging.FileHandler("log.txt")#日志输出到log.txt中
handler.setLevel(logging.WARNING) #只输出hander和logger的setLeverl级别更高的一级
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
logger.info("Finish")
log.tx内容为:
2021-11-14 17:05:48,407 - __main__ - WARNING - warning message
2021-11-14 17:05:48,407 - __main__ - ERROR - error message
2021-11-14 17:05:48,407 - __main__ - CRITICAL - critical message
(3)使用json文件配置
使用JSON配置文件:
{
"version":1,
"disable_existing_loggers":false,
"formatters":{
"simple":{
"format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
}
},
"handlers":{
"console":{
"class":"logging.StreamHandler",
"level":"DEBUG",
"formatter":"simple",
"stream":"ext://sys.stdout"
},
"info_file_handler":{
"class":"logging.handlers.RotatingFileHandler",
"level":"INFO",
"formatter":"simple",
"filename":"info.log",
"maxBytes":"10485760",
"backupCount":20,
"encoding":"utf8"
},
"error_file_handler":{
"class":"logging.handlers.RotatingFileHandler",
"level":"ERROR",
"formatter":"simple",
"filename":"errors.log",
"maxBytes":10485760,
"backupCount":20,
"encoding":"utf8"
}
},
"loggers":{
"my_module":{
"level":"ERROR",
"handlers":["info_file_handler"],
"propagate":"no"
}
},
"root":{
"level":"INFO",
"handlers":["console","info_file_handler","error_file_handler"]
}
}
使用程序如下:
import json
import logging.config
import os
def setup_logging(default_path = "logging.json",default_level = logging.INFO,env_key = "LOG_CFG"):
path = default_path
value = os.getenv(env_key,None)
if value:
path = value
if os.path.exists(path):
with open(path,"r") as f:
config = json.load(f)
logging.config.dictConfig(config)
else:
logging.basicConfig(level = default_level)
def func():
logging.info("start func")
logging.info("exec func")
logging.info("end func")
if __name__ == "__main__":
setup_logging(default_path = "logging.json")
func()
(4)通过YAML文件配置
使用YAML文件进行配置:
version: 1
disable_existing_loggers: False
formatters:
simple:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
console:
class: logging.StreamHandler
level: DEBUG
formatter: simple
stream: ext://sys.stdout
info_file_handler:
class: logging.handlers.RotatingFileHandler
level: INFO
formatter: simple
filename: info.log
maxBytes: 10485760
backupCount: 20
encoding: utf8
error_file_handler:
class: logging.handlers.RotatingFileHandler
level: ERROR
formatter: simple
filename: errors.log
maxBytes: 10485760
backupCount: 20
encoding: utf8
loggers:
my_module:
level: ERROR
handlers: [info_file_handler]
propagate: no
root:
level: INFO
handlers: [console,info_file_handler,error_file_handler]
使用程序如下:
import yaml
import logging.config
import os
def setup_logging(default_path = "logging.yaml",default_level = logging.INFO,env_key = "LOG_CFG"):
path = default_path
value = os.getenv(env_key,None)
if value:
path = value
if os.path.exists(path):
with open(path,"r") as f:
config = yaml.load(f)
logging.config.dictConfig(config)
else:
logging.basicConfig(level = default_level)
def func():
logging.info("start func")
logging.info("exec func")
logging.info("end func")
if __name__ == "__main__":
setup_logging(default_path = "logging.yaml")
func()
参考:
time:https://www.cnblogs.com/tkqasn/p/6001134.html
logging:https://blog.csdn.net/pansaky/article/details/90710751#t0
pathlib:https://www.cnblogs.com/heniu/p/12872604.html