12.1 sys 模块
sys 模块中一些重要的函数和变量
函数/变量 | 函数返回数据类型 变量数据类型 | 描述 |
argv | 列表 | 命令行参数,argv[0]表示脚本名称,argv[1]表示第1个命令行参数,以此类推 |
exit([arg]) | None | arg表示调用当前脚本的返回值,取值范围:0~255(无符号字节) |
modules | 字典 | 当前已经装载模块的列表 |
path | 列表 | 获取或设置搜索模块的路径列表,如果import的模块不在path列表字典的路径,可以使用path.append方法添加模块所在的路径 |
platform | 字符串 | 获取当前操作系统的平台标识符,如Mac OSX的值是darwin,Windows的值是win32 |
stdin | TextOWrapper类 | 标准输入流 |
stdout | TextOWrapper类 | 标准输出流 |
stderr | TextOWrapper类 | 标准错误流 |
test.py
import sys
# 向sys.path列表添加my模块所在的路径
sys.path.append('./')
import my
# 调用my模块中定义的greet函数
my.greet('Bill')
# 输出已经装载的my模块的信息(使用modules字典)
print(sys.modules['my'])
# 输出modules字典中存储my模块value的数据类型
print(type(sys.modules['my']))
# 输出当前的操作系统平台标识符
print(sys.platform)
# 输出当前脚本文件的文件名(包含完整的路径)
print(sys.argv[0])
# 如果有命令行参数,则输出第1个命令行参数的值,sys.argv列表的长度至少为1
# 因为第一个列表元素永远是当前脚本文件的路径
if len(sys.argv) == 2:
print(sys.argv[1])
my.greet(sys.argv[1])
# 从标准输入流采集长度为6的字符串
s = sys.stdin.read(6)
print(s)
# 向标准输入流中写入一个字符串
sys.stdout.writelines('hello world')
print()
# 向标准错误流中写入一个字符串
sys.stderr.writelines('error')
# 设置当前脚本文件的返回值,通过invoke.py可以获取
sys.exit(123)
my.py
def greet(name):
print('Hello %s' % name)
由于回车也算一个字符,所以输入了“Hello”,按 Enter键,系统就会认为已经向stdin输入了个字符。最后使用sys.exit函数退出当前脚本,并通过该函数指定了脚本的返回值。要注意的是,调用sys.exit 函数会退出整个脚本,所以在sys.exit函数后面的代码都不会被执行,因此,sys.exit函数通常会在脚本的最后或退出脚本时调用。标准输出流和标准错误流都属于输出流,都会在控制台上输出文本。只不过在很多IDE上,向标准错误流写入文本,会以红色字体显示。
invoke.py
import subprocess
# 执行test.py脚本文件,并得到该脚本的返回结果
output = subprocess.getstatusoutput('python test.py Mike')
print(output)
print(output[0])
getstatusoutput函数返回了一个元组,第1个元素值就是被调用脚本文件的返回值(本例是123),第2个元素值是被调用脚本的输出结果。由于test.py 中需要从标准输入流采集字符串,所以该脚本文件被调用时也需要输入一个长度为6的字符串(本例是“Hello”),代码才会往下执行。
invoke.py 脚本执行结果
其中脚本的相对位置如下:
12.2 OS 模块
os模块以及子模块path中包含了大量获取各种系统信息,以及对系统进行设置的函数。
12.2.1 获取与改变工作目录
使用 getcwd 函数获取了当前的工作目录,并输出该目录,然后通过chdir 函数将当前的工作目录设为上一级目录。
import os
# 获取系统信息
# 返回当前的工作目录
print('当前工作目录:',os.getcwd())
# 返回path指定的文件夹包含的文件或文件夹的名字的列表。
print('工作目录中包含的文件或文件夹的名字的列表')
print(os.listdir(os.getcwd()))
# 改变当前工作目录
os.chdir('../')
print('改变后的工作目录',os.getcwd())
print('新的工作目录中包含的文件或文件夹的名字的列表')
print(os.listdir(os.getcwd()))
当前工作目录: D:\untitled01
工作目录中包含的文件或文件夹的名字的列表
['.idea', 'invoke.py', 'my.py', 'test.py', 'venv', '__pycache__']
改变后的工作目录 D:\
新的工作目录中包含的文件或文件夹的名字的列表
['$RECYCLE.BIN', '360liulanqi', '360yasuo', '360极速浏览器下载', 'Download', 'fuxin', 'HONOR Magic-link', 'navicat150', 'notepad++', 'pycharm2019', 'QQ', 'QQMusicCache', 'QQyinyue', 'Sougou', 'System Volume Information', 'untitled01', 'VM', 'VM01', 'VM02', 'VM03', 'WeiXin', 'xmind8', 'Xshell7', '安装包']
12.2.2 文件与目录操作
在os模块中提供了一些操作目录和文件的函数。这些函数的功能描述如下:
- mkdir(dirname, permissions) : 创建目录,dirname表示目录名,如果dirname 指定的目录名存在,则抛出OSError异常。permissions 表示目录的权限。在 Linux或 Mac OS X上可以设置目录读®、写(w)和执行(x)权限。permissions参数值一般是一个八进制的数值。如0o777表示最高的权限,7表示同时具有rwx权限。
- makedirs(dirname,permissions,exist_ok) : 与mkdir函数类似,用于建立目录,但dirname指定的目录可以是多级的,而且上一级不存在,也会建立上一级的目录。例如,dirname参数的值是x/y/z。也就是说,需要在当前目录建立三级目录。如果使用mkdir函数,并且x或y目录不存在,那么程序会直接抛出OSError错误,但使用makedirs函数建立目录,会连同x和y一起建立。makedirs函数最后一个参数的值为False,当目录存在时,会抛出OSError异常,否则即使目录存在,也不会抛出异常。
- rmdir(dirname) : 删除dirname参数指定的目录,如果目录不为空,则抛出一个OSError异常。
- removedirs(dirname) : 删除 dirname参数指定的目录,dirname参数可以指定多级目录。如x/y/z,该函数会同时删除x、y和z目录。不过如果某一级目录不为空,那么该目录以及所有的父目录都不会被删除。例如,如果在y目录中除了有一个z子目录外,还有一个test.txt 文件,那么在删除x/y/z目录时,只会删除y目录中的z子目录,x和y目录都不会被删除。
- remove(filename) : 删除filename参数指定的文件。
- rename(src,dst) : 将src参数指定的文件(目录)名改成dst参数指定的文件名。
- renames(src,dst) : 与rename函数的功能类似,只是 src和 dst可以是多级目录(最后一级可以是文件名)。该函数会将每一级的目录都改成对应的目录名,如可以将x/y/z 改成a/b/c。该函数会将x改成a,y改成b,z改成c。
import os
# 判断当前目录下是否存在newdir1目录
if not os.path.exists('newdir1'):
# 如果不存在创建一个newdir1目录
os.mkdir('newdir1')
if not os.path.exists('newdir2'):
# 创建newdir2目录,并设置目录权限,需要使用管理员权限可以读
os.mkdir('newdir2',0o377)
# 不能创建多级目录 os.mkdir('a/b/c/d')
# 可以创建多级目录,且不会抛出异常
os.makedirs('x/y/z',0o733,True)
# 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。
try:
# 删除path指定的空目录,如果目录非空,则抛出一个OSError异常
os.rmdir('newdir1')
except OSError as e:
print(e)
# 如果目录为空,删除所有的目录,如果某一层目录不为空,那么包含这一层目录的父目录都不会被删除
os.removedirs('x/y/z')
# 删除指定文件
# os.remove('test.txt')
if not os.path.exists('mydir'):
os.mkdir('mydir')
# 将mydir目录重命名为yourdir
os.rename('mydir','yourdir')
if os.path.exists('test.txt'):
# 将test.txt文件重命名为data.txt
os.rename('test.txt','data.txt')
if os.path.exists('bill/mike/john'):
# 递归地对目录进行更名,也可以对文件进行更名。
os.renames('bill/mike/john', 'ok1/ok2/ok3')
if os.path.exists('a/aa.txt'):
os.renames('a/aa.txt','b/bb.txt')
# 删除b目录下的bb.txt文件
os.remove('b/bb.txt')
12.2.3 软连接与硬链接
软链接和硬链接是Linux 和 Mac OS X的概念。软链接就像Windows中的快捷方式,只是保存源文件或目录的引用,而且只有固定尺寸。硬链接只能针对文件建立,这是因为硬链接是将整个文件复制一份,相当于一个副本,所以在建立硬链接时会进行限制。软链接和硬链接都是同步的。也就是说,只要修改软链接文件或硬链接文件,源文件的内容就会变,反之亦然。
不过这里的同步指的是修改。删除源文件时,硬链接和软链接文件不会被删除。由于硬链接文件是源文件的一个副本,当删除源文件后,硬链接文件将变成一个独立的文件,而软链接文件仍然指向被删除的源文件,但由于源文件已经不存在,所以打开软链接文件后没有任何显示。
在os模块中提供了两个函数,分别用来建立软链接文件和硬链接文件。其中,symlink函数用来建立软链接文件,link 函数用来建立硬链接文件。这两个函数各自都有两个参数,第1个参数表示源文件,第2个参数表示链接文件名。
import os
if os.path.exists('data.txt') and not os.path.exists('slink.txt'):
# 建立软链接
os.symlink('data.txt','slink.txt')
if os.path.exists('data.txt') and not os.path.exists('link.txt'):
# 建立硬链接
os.link('data.txt','link.txt')
如果链接文件存在,那么使用symlink函数和link函数建立软链接文件和硬链接文件时会抛FileExistsError异常,所以要使用path子模块中的exists函数进行校验。
注意,symlink函数在Windows中使用时要拥有管理员权限,或用管理员权限打开命令行工具,然后才可以在命令行工具中执行symlink函数,否则会抛出“OSError: symbolic link privilege not held异常。
12.2.4 杂项
在os模块中还提供了很多用于获取和设置系统信息的函数和变量。
- sep变量 : 返回当前OS 的路径分隔符,在 Windows中是反斜杠(\),在Linux和 Mac OS X中是斜杠(/)。
- pathsep变量 : 返回环境变量中路径之间的分隔符,在 Windows中是分号(;),在Linux和 MacOS X中是冒号(:)。
- name变量 : 返回当前OS的名称。
- environ变量 : 以字典形式返回系统中所有环境变量的值。
- getenv函数 : 获取指定的环境变量的值,通过参数指定环境变量名。
- putenv函数 : 设置指定环境变量的值,通过参数指定环境变量名和环境变量的值。
- system函数 : 执行命令,通过参数指定要执行的命令。
import os
import subprocess
# 输出路径分隔符
print(os.sep)
# 输出环境变量中路径的分隔符
print(os.pathsep)
# 输出当前os的名称
print(os.name)
# 输出当前系统中的所有环境变量的值
print(os.environ)
# 输出PATH环境变量的值
print(os.environ['PATH'])
# 使用getenv函数获取PATH环境变量的值
print(os.getenv('PATH'))
# 执行exe文件
output = subprocess.getstatusoutput('exe')
# 输出执行结果,没有发现文件
print(output)
# 将exe文件所在的目录/temp添加到PATH环境变量中
os.putenv('PATH', os.getenv('PATH') + os.pathsep+ '/temp/exe')
# 执行exe文件
output = subprocess.getstatusoutput('exe')
# 输出运行结果
print(output)
# 再次输出PATH环境变量
print(os.getenv('PATH'))
# 执行"ls -al"命令
os.system('ls -al')
使用putenv函数可以修改环境变量,但这种修改只是临时的,并不会影响系统的环境变量只是在当前Python进程中会使用这些修改后的环境变量。使用getenv函数或environ变量重新获取这些环境变量时获取的仍然是未修改之前的值。
12.3 集合、堆和双端队列(heap模块、deque类)
12.3.1 集合
从Python2.3开始,集合就通过set类型成为语言的一部分,因此,在Python3中可以直接使用集合类型(set),而不需要再引用sets模块(这个模块已经被去除了)。Python语言中的集合和数学中集合的概念非常类似。在数学中集合有如下三个特性。
- 无序性 : 集合中每个元素的值都是平等的,元素之间是无序的。
- 互异性 : 集合中任意两个元素都是不同的,即每个元素只能出现一次。
- 确定性 : 集合中每个元素都是确定的,对于一个值来说,要么属于该集合,要么不属于该集合。所以集合、列表和字典都不能作为集合的元素值,因为它们都是可变的。
Python语言中的集合也同样满足这三个特性,而且同样支持集合的标准操作,如创建集合、合并集合、集合相交、求集合的差等。在创建集合类set的实例时,需要为set类的构造方法提供一个列表或元组类型的值,用于建立集合的数据源。也就是说,set类可以将列表或元组转换为集合,在转换的过程中,会去除重复的值,并且列表或元组中元素的顺序可能被打乱,因为集合中的元素是无序的。
# 创建一个有10个元素的集合
set1 = set(range(10))
# 输出set1的类型 <class 'set'>
print(type(set1))
# 运行结果
print(set1)
# 将字符串中的每一个字符作为元素添加进集合,因为字符串可看作字符的列表
# 将重复的集合元素去掉
set2 = set('hello')
print(set2)
# 利用字符串列表建立集合,去除重复的字符串,字符串的顺序会打乱
set3 = set(['Bill','John','Mike','John'])
print(set3)
# 利用一个元组建立一个集合
a = set((1,2,3))
# 利用列表建立一个集合
b = set([3,5,1,7])
# 利用union方法合并a集合和b集合
print(a.union(b))
# 利用"|"运算符合并a集合和b集合
print(a | b)
# 利用"&"运算符a集合和b集合的交集
print(a & b)
# 利用intersection方法求a集合和b集合的交集
print(a.intersection(b))
# 使用列表创建一个集合
c = set([2,3])
# 判断c集合是否为a集合的子集,True
print(c.issubset(a))
# 判断a集合是否为c集合的子集,False
print(a.issubset(c))
# 判断c集合是否为a集合的超集,False
print(c.issuperset(a))
# 判断a集合是否为c集合的超集,True
print(a.issuperset(c))
# 使用列表创建一个集合
d = set([1,2,3])
# 判断a集合和d集合是否相等,True
print(a == d)
# 得到a集合与b集合的差
print(a.difference(b))
print(a - b)
# 得到a集合与b集合的对称差
print(a.symmetric_difference(b))
print(a ^ b)
print((a - b) | (b - a))
# 使用copy方法将a复制一份,并将该副本赋给变量x
x = a.copy()
# 判断a与x是否相同,False
print(x is a)
# 向集合x中添加一个新的元素
x.add(30)
print(x)
print(a)
print(d)
# 判断1是否属于集合d,True
print(1 in d)
# 判断10是否属于集合d,False
print(10 in d)
由于集合是可变的,所以不能作为元素值添加到集合中,也不能作为字典的key。不过可以利用frozenset类型将集合变成只读的,这样就可以作为集合元素和字典的 key。
a = set([1,2])
b = set([10,20])
# 向a集合中添加一个元素值
a.add(4)
print(a)
# 集合b不能作为元素值添加进集合a,抛出异常
# a.add(b)
# 将集合b变成只读的集合,成功添加进集合a
a.add(frozenset(b))
print(a)
# 定义一个字典
d = {'Bill':30,'Mike':40}
# 集合a同样不能作为字典的key,执行下面的代码会抛出异常
# d[a] = 60
# 将集合b变成只读的集合,成功添加进字典
d[frozenset(a)] = 60
print(d)
t = [1,2,3]
tt = (1,2,3)
# 列表不能作为字典的key,会抛出异常
# d[t] = 111
# 列表不能作为集合的元素,会抛出异常
# a.add(t)
# 字典不能作为集合的元素,会抛出异常
# a.add(d)
# 元组可以作为集合的元素
a.add(tt)
print(a)
12.3.2 堆
堆也是一种众所周知的数据结构,它是优先队列中的一种。使用优先队列能以任意顺序增加元素值,并能快速找到最小(大)的元素值,或前n个最小或最大的元素值,这要比用于列表的min函数和max函数高效得多。
heapq模块中的常用函数
函数 | 描述 |
heappush(heap,value) | 将value加入堆 |
heappop(heap) | 将堆中的最小值弹出,并返回该最小值 |
heapify(heap) | 将列表转换为堆,也就是重新安排列表中元素的顺序 |
heapreplace(heap,value) | 将堆中的最小值弹出,并同时将value入堆 |
nlargest(n, iter) | 返回可迭代对象(如列表)中前n个最大值,以列表形式返回 |
nsmallest(n,iter) | 返回可迭代对象(如列表)中前n个最小值,以列表形式返回 |
merge(*iter, key) | 合并多个有序的迭代对象,如果指定key,则对每个元素的排序规则会利用key 指定的函数 |
from heapq import *
from random import *
data = [1, 2, 3, 4, 5, 6,7,8,9]
# 定义一个堆,其实堆就是一个列表,只是通过heapq模块中的函数利用堆算法来改变列表中的元素而已
heap = []
for n in data:
# 利用choice函数从data列表中随机选择9个数(可能有重复的数)
value = choice(data)
# 使用heappush函数将value添加进堆
heappush(heap,value)
print(heap)
# 将2.5添加进堆
heappush(heap,2.5)
print(heap)
# 弹出heap中最小的值,并获取这个最小的值
print(heappop(heap))
print(heap)
data1 = [6,3,1,12,8]
# 将data1转换为堆(直接修改了data1)
heapify(data1)
print(data1)
# 弹出最小的值,并将100添加进堆
heapreplace(data1, 100)
print(data1)
# 得到堆中前n个最大的值
print(nlargest(1,data1))
print(nlargest(2,data1))
# 得到堆中前n个最小的值
print(nsmallest(1,data1))
print(nsmallest(3,data1))
# 合并多个有序的列表,并得到一个新的有序列表
print(list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])))
# 合并多个有序的列表,并按列表元素值的长度进行排序
print(list(merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len)))
12.3.3 双端队列
双端队列不同于普通的队列。对于普通的队列来说,只能操作队列的头,而不能操作队列的尾,也就是先进先出操作。双端队列是普通队列的扩展,在队列的头和尾都可以进行队列的操作,所以对一组值的两头进行操作,使用双端队列是非常方便的。
使用双端队列需要导入collections模块中的 deque类。该类中提供了若干个方法用于操作双端队列,例如,append方法可以将值添加到队列的尾部,而 appendleft方法可以将值添加到队列的头部pop方法可以弹出队列尾部的最后一个值,并返回这个值。popleft方法可以弹出队列头部的第1个值并返回这个值。
from collections import deque
# 创建一个包含10个数字的双端队列
q = deque(range(10))
print(q)
# 在双端队列d的尾部追加值
q.append(100)
q.append(-100)
print(q)
# 在双端队列d的头部追加值
q.appendleft(20)
print(q)
# 弹出队尾的值
print(q.pop())
print(q)
# 弹出队首的值
print(q.popleft())
print(q)
# 将双端队列中的元素向左移动2个位置,也就是队首的元素会移动到队尾
q.rotate(-2)
print(q)
# 将双端队列中的元素向右移动4个位置,也就是队尾的元素会移动到队首
q.rotate(4)
print(q)
# 创建一个双端队列q1
q1 = deque(['a','b'])
# 将q1追加到q的后面
q.extend(q1)
print(q)
# 将q1追加到q的前面,这是q1会倒序排列
q.extendleft(q1)
print(q)
12.4 时间、日期与日历(time 模块)
Python程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。Python提供的time、datetime和calendar模块可以用于格式化日期和时间。时间间隔是以秒为单位的浮点数。每个时间戳使用从1970年1月1日午夜(历元)到现在经过的时间来表示。
import time
ticks = time.time()
#运行结果:当前时间截为:1511675087.7990139
print("当前时间戳为:",ticks)
12.4.1 时间元组
在 Python语言中,时间用一个元组表示。表示时间的元组有9个元素,这9个元素都有其对应的属性,所以时间元组中的每一个元素值既可以通过属性获得,也可以通过索引获得。
时间元组中的元素属性与描述
属性 | 描述 | 值 |
tm_year | 4位数字的年 | 2008、2016等 |
tm_mon | 月 | 1~12 |
tm_mday | 日 | 1~31 |
tm_hour | 小时 | 0~23 |
tm_min | 分钟 | 0~59 |
tm_sec | 秒 | 0~61 (60或61是闰秒) |
tm_wday | 一周的第几日 | 0~6(0是周一) |
tm_yday | 年的第几日 | 1~366(儒略历) |
tm_isdst | 夏令时 | 1表示夏令时,0表示不是夏令时,-1表示未知。默认值是-1 |
import time
# 获取当前时间
localtime = time.localtime(time.time())
print ("本地时间为 :", localtime)
print('年','=', localtime.tm_year)
print('月','=', localtime.tm_mon)
print('日','=', localtime.tm_mday)
print('一周的第%d' % localtime[7])
# 获取一个可读的时间
localtime = time.asctime( time.localtime(time.time()) )
print ("本地时间为 :", localtime)
12.4.2 格式化日期和时间
在不同的场景,需要显示不同格式的日期和时间,有的场景要求显示完整的日期和时间,有的场景仅仅要求显示4位的年。这就要求在输出日期和时间之前要先进行格式化。
格式化日期和时间的符号
格式化符号 | 描述 |
%y | 两位数的年份(00~99) |
%Y | 四位数的年份(000o~9999) |
%m | 两位数的月份(O1~12) |
%d | 月内的某一天(0~31) |
%H | 24小时制的小时数(0~23) |
%l | 12小时制的小时数(1~12) |
%M | 分钟数(O~59) |
%S | 秒(0~59) |
%a | 本地简化星期名称 |
%A | 本地完整星期名称 |
%b | 本地简化月份名称 |
%B | 本地完整月份名称 |
%c | 本地日期和时间 |
%j | 一年中的第几天(0~366) |
%p | 本地A.M.或P.M.的等价符号,一般与12小时制的小时数一起使用 |
%U | 年中的星期数,星期日为一个星期的开始 |
%w | 星期(0~6),星期日为一个星期的开始 |
%w | 一年中的星期数,星期一为一个星期的开始 |
%x | 本地日期 |
%X | 木地时间 |
%Z | 当前时区的名称 |
%% | %号本身 |
Python语言中所有用于格式化日期和时间的符号都以百分号(%)开头,如“%Y-%m-%d”会将日期格式化为如“2021-06-12”的形式。
import time
import locale
# 设置日期和时间为中文UTF-8格式,格式化字符串中支持中文
locale.setlocale(locale.LC_ALL, 'zh_CN.UTF-8')
# 格式化
print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
print (time.strftime("%Y年%m月%d日 %H时%M分%S秒", time.localtime()))
print(time.strftime('%Y{y}%m{m}%d{d} %H{H}%M{M}%S{S}').format(y='年', m='月', d='日',H='时', M='分', S='秒'))
print(time.strftime('今天是%A',time.localtime()))
要注意的是,如果格式化字符串中包含中文,必须用locate模块中的setlocale函数将日期和时间的格式设为中文的UTF-8格式,否则无法成功对日期和时间格式化。可以使用locate -a命令查询,这些命令仅仅针对Linux 和 Mac OS X系统。
12.4.3 时间戳的增量
通过time模块的time函数可以获取当前时间的时间戳(浮点数格式),时间戳可以加上或减去一个整数(n),这就是时间戳的增量,单位是秒。也就是说,当前时间戳加10表示未来10s,减10表示过去10s。如果想得到未来1h的时间戳,需要将time函数的返回值加3600。
import time
# 获取当前时间戳
time1 = time.time()
# 未来1min
time2 = time1 + 60
# 未来1h
time3 = time1 + 60 * 60
# 过去1天
time4 = time1 - 60 * 60 * 24
# 将时间戳转换为时间元组
time1 = time.localtime(time1)
time2 = time.localtime(time2)
time3 = time.localtime(time3)
time4 = time.localtime(time4)
# 格式化输出
print (time.strftime("%Y-%m-%d %H:%M:%S", time1))
print (time.strftime("%Y-%m-%d %H:%M:%S", time2))
print (time.strftime("%Y-%m-%d %H:%M:%S", time3))
print (time.strftime("%Y-%m-%d %H:%M:%S", time4))
12.4.4 计算日期和时间的差值
datetime模块中的datetime类允许计算两个日期的差值,可以得到任意两个日期之间的天数以剩余的秒数。通过datetime模块的 timedelta 函数还可以得到一个时间增量,如 timedetla(hours=2)可得到往后延两个小时的时间增量。
import datetime
# 定义第1个日期
d1 = datetime.datetime(2017, 5, 12)
# 定义第2个日期
d2 = datetime.datetime(2021, 12, 12)
# 计算两个日期之间的天数
print((d2 - d1).days)
# # 定义第1个日期+时间
d1 = datetime.datetime(2017, 5, 12,10,10,10)
# # 定义第2个日期+时间
d2 = datetime.datetime(2021, 12, 25,10,10,40)
# 输出两个日期的差
print(d2 - d1)
# 输出两个日期相差的秒数(除去了整天数)
print((d2 - d1).seconds)
# 获取当前日期(datetime类型)
d1 = datetime.datetime.now()
# 当前时间往后延期10小时
d2 = d1 + datetime.timedelta(hours=10)
import time
# 将时间戳转化为时间元组,并格式化
d2 = time.localtime(d2.timestamp())
print (time.strftime("%Y-%m-%d %H:%M:%S", d2))
12.4.5 获取某月和某年的日历
使用calendar模块中的month函数,可以得到某月的日历,以字符串形式返回。如果使用calendar函数,可以获取某一年12个月的日历,也是以字符串形式体现。
import calendar
import locale
# 返回2020年1月的日历
cal = calendar.month(2021, 1)
print(cal)
# 设置日期格式为中文UTF-8
locale.setlocale(locale.LC_ALL, 'zh_CN.UTF-8')
cal = calendar.month(2021, 1)
print(cal)
# 恢复默认的日期格式(英文),并显示12个月的日历
locale.setlocale(locale.LC_ALL, '')
print(calendar.calendar(2021))
12.5 随机数(random 模块)
在 random模块中封装了多个函数用于产生各种类型的随机数,这些函数有的可以产生单值随机数,有的可以产生一组随机数,还有的可以打乱列表原来的顺序,类似于洗牌。random模块中常用函数及描述如下:
- randint(m,n) : 产生m~n的随机整数,包括m和 n。
- random() : 产生0~1的随机浮点数,包括0,但不包括1。
- uniform(m,n) : 产生m~n的随机浮点数,m和n可以是浮点数,包括m和n。
- randrange(m,n,step) : 在一个递增的序列中随机选择一个整数。其中,step是步长。如randrange(1,6,2),该函数就会在列表[1,3,5]中随机选择一个整数。
- choice(seq) : 从 seq指定的序列中随机选择一个元素值。seq指定的列表元素可以是任意类型的值。
- shuffle(seq) : 把 seq指定的序列中元素的顺序打乱,该函数直接修改原有的序列。
import random
# 产生1-100的随机数
print(random.randint(1,100))
# 产生0-1的随机数
print(random.random())
# 从[1,4,7,10,13,16,19]中随机选一个数
print(random.randrange(1, 20, 3))
# 产生一个1-100.5的随机浮点数
print(random.uniform(1, 100.5))
intList = [1,2,3,4,5,6,7,8,9,'a','b','c','d']
# 从列表中随机选一个元素值
print(random.choice(intList))
# 从列表中随机选择3个随机数,并生成一个新的序列
newList = random.sample(intList, 3)
print(newList)
# 随机重新排列列表中的额元素值,直接修改原列表
random.shuffle(intList)
print(intList)
12.6 数学(math 模块)
在math模块中封装了很多与数学有关的函数和变量,如取整、计算幂值、平方根、三角函数等。
import math
print('圆周率', '=', math.pi)
print('自然常数', '=', math.e)
# 取绝对值
print(math.fabs(-1.0))
# 向上取整
print(math.ceil(1.3))
# 向下取整
print(math.floor(1.7))
# 计算2的10次方
print(math.pow(2,10))
# 计算8的平方根
print(math.sqrt(8))
# 计算Π/2的正弦值
print(math.sin(math.pi / 2))
# 计算Π的余弦
print(math.cos(math.pi))
# 计算Π/4的正切
print(math.tan(math.pi / 4))