常用模块:time、datetime、random、os、sys
collections模块
在内置数据类型(dict、list、set、tuple)的基础上,
collections模块还提供了几个额外的数据类型:
Counter、deque、defaultdict、namedtuple和OrderedDict等
collections模块 总览:
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
collections模块 具体介绍:
1、namedtuple(具名函数)
tuple可以表示不变集合,例如一个点的二维坐标就可以表示为 p = (1,2);
而namedtuple可以指名道姓地定义和取值
定义方式:namedtuple(元组名称,可迭代对象)
可迭代对象也可以是字符串(将元素名称空格隔开即可)。目的主要是按位置接收接收值
```python
from collections import namedtuple # 导入collections模块
res = namedtuple('people',['name','age'])
'''定义一个具名元组,元组名称是people,用res接收,那res也可以看作是元组名咯
(只要后边是一个可迭代对象就行例如列表。特殊的:字符串也是可以的,空格隔开就行)
定义方式二:res = namedtuple('people', 'name age')
'''
b = res('jason','24') # 相当于‘jason’赋值给‘name’;'24'赋值给'age'
print(b)
print(b.name)
'''执行结果
people(name='jason', age='24')
jason
'''
```
2、deque双端队列
回顾:队列:现进先出(FIFO first in first out)
import queue
q = queue.Queue() # 生成队列对象
q.put('first') # 往队列中添加值
q.put('second')
q.put('third')
print(q.get()) # 朝队列要值
print(q.get())
print(q.get())
print(q.get()) # 如果队列中的值取完了 程序会在原地等待 直到从队列中拿到值才停止
'''执行结果
first
second
third
# 此时程序并没有结束,而是一直hang住的状态
'''
双端队列作用:
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
deque除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,
这样就可以非常高效地往头部添加或删除元素
from collections import deque
q = deque(['a','b','c'])
q.append(1)
q.appendleft(2)
"""
队列不应该支持任意位置插值
只能在首尾插值(不能插队)
"""
q.insert(0,'哈哈哈') # 特殊点:双端队列可以根据索引在任意位置插值
print(q.pop())
print(q.popleft())
print(q.popleft())
'''执行结果
1
哈哈哈
2
'''
3、OrderDict
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用 OrderedDict
# 注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:
from collections import OrderedDict
od = OrderedDict()
od['z'] = 1
od['y'] = 2
od['x'] = 3
print(od.keys()) # 按照插入的Key的顺序返回
# 执行结果
['z', 'y', 'x']
4、defaultdict
使用dict
时,如果引用的Key不存在,就会抛出KeyError
。
如果希望key不存在时,返回一个默认值,就可以用defaultdict
:
from collections import defaultdict
values = [44,55,66,77,88,99,]
my_dict = defaultdict(list) # 后续该字典中新建的key对应的value默认就是列表
print(my_dict['aaa'])
for value in values:
if value>66:
my_dict['k1'].append(value) # 利用方式:key.append直接将value放到value中
else:
my_dict['k2'].append(value)
print(my_dict)
'''对比dict的实现方法:
当dict的键值对不存在时,要新增键值对的方式;
而defaultdict可以忽略,因为他设置了默认的value
'''
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = {}
for value in values:
if value>66:
if my_dict.has_key('k1'):
my_dict['k1'].append(value)
else:
my_dict['k1'] = [value]
else:
if my_dict.has_key('k2'):
my_dict['k2'].append(value)
else:
my_dict['k2'] = [value]
5、Counter
Counter类的目的是用来跟踪元素出现的次数。
以字典的键值对形式存储,其中元素作为key,其计数作为value
from collections import Counter
s = 'abcdeabcdabcaba'
res = Counter(s)
print(res,type(res))
for i in res:
print(i)
'''执行结果
Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1}) <class 'collections.Counter'>
a
b
c
d
e
'''
time与datetime
时间的三种表示形式:
概述:时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的
1、时间戳 (timestamp):
通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。
我们运行“type(time.time())”,获取时间戳,返回的是float类型。
2、格式化时间(目的是展示给人看的)
例如:%Y 四位数的年份表示(000-9999); %m 月份(01-12); %d 月内中的一天(0-31)
3、结构化时间(元组 struct_time)
#导入时间模块
>>>import time
#时间戳
>>>time.time()
1500875844.800804
#时间字符串
>>>time.strftime("%Y-%m-%d %X")
'2017-07-24 13:54:37'
>>>time.strftime("%Y-%m-%d %H-%M-%S")
'2017-07-24 13-55-04'
#时间元组:localtime将一个时间戳转换为当前时区的struct_time
>>>time.localtime()
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=18, tm_hour=18, tm_min=48, tm_sec=42, tm_wday=3, tm_yday=199, tm_isdst=0)
>>>time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24,
tm_hour=13, tm_min=59, tm_sec=37,
tm_wday=0, tm_yday=205, tm_isdst=0)
# time
import time
print(time.time())
print(time.strftime('%Y-%m-%d'))
print(time.strftime('%Y-%m-%d %H:%M:%S'))
print(time.strftime('%Y-%m-%d %X')) # %X等价于%H:%M:%S
print(time.strftime('%H:%M'))
print(time.strftime('%Y/%m'))
'''执行结果
1563447127.5767193
2019-07-18
2019-07-18 18:52:07
2019-07-18 18:52:07
18:52
2019/07
'''
# datetime
import datetime
print(datetime.date.today()) # date>>>:年月日
print(datetime.datetime.today()) # datetime>>>:年月日 时分秒
res = datetime.date.today()
res1 = datetime.datetime.today()
print(res,type(res))
print(res.year)
print(res.month)
print(res.day)
print(res.weekday()) # 0-6表示星期 0表示周一
'''执行结果
2019-07-18
2019-07-18 19:55:13.331872
2019-07-18 <class 'datetime.date'>
2019
7
18
3
'''
几种时间格式的转换
#时间戳-->结构化时间
#time.gmtime(时间戳) #UTC时间,与英国伦敦当地时间一致
#time.localtime(时间戳) #当地时间。例如我们现在在北京执行这个方法:与UTC时间相差8小时,UTC时间+8小时 = 北京时间
>>>time.gmtime(1500000000)
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
>>>time.localtime(1500000000)
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0)
#结构化时间-->时间戳
#time.mktime(结构化时间)
>>>time_tuple = time.localtime(1500000000)
>>>time.mktime(time_tuple)
1500000000.0
#结构化时间-->字符串时间
#time.strftime("格式定义","结构化时间") 结构化时间参数若不传,则显示当前时间
>>>time.strftime("%Y-%m-%d %X")
'2017-07-24 14:55:36'
>>>time.strftime("%Y-%m-%d",time.localtime(1500000000))
'2017-07-14'
#字符串时间-->结构化时间
#time.strptime(时间字符串,字符串对应格式)
>>>time.strptime("2017-03-16","%Y-%m-%d")
time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1)
>>>time.strptime("07/24/2017","%m/%d/%Y")
time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
# 计算时间差
import time
true_time=time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S'))
time_now=time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S'))
dif_time=time_now-true_time
struct_time=time.gmtime(dif_time)
print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1,
struct_time.tm_mday-1,struct_time.tm_hour,
struct_time.tm_min,struct_time.tm_sec))
# 执行结果:过去了0年0月1天2小时30分钟0秒
random模块
>>> import random
#随机小数
>>> random.random() # 大于0且小于1之间的小数
0.7664338663654585
>>> random.uniform(1,3) #大于1小于3的小数
1.6270147180533838
#恒富:发红包
#随机整数
>>> random.randint(1,5) # 大于等于1且小于等于5之间的整数
>>> random.randrange(1,10,2) # 大于等于1且小于10之间的奇数
#随机选择一个返回
>>> random.choice([1,'23',[4,5]]) # #1或者23或者[4,5]
# random.choice( seq ) seq -- 可以是一个列表,元组或字符串。
#随机选择多个返回,返回的个数为函数的第二个参数
>>> random.sample([1,'23',[4,5]],2) # #列表元素任意2个组合
# random.sample([1,'23',[4,5]],n) # #列表元素 任意n个组合
[[4, 5], '23']
#打乱列表顺序
>>> item=[1,3,5,7,9]
>>> random.shuffle(item) # 打乱次序
>>> item
[5, 1, 3, 7, 9]
>>> random.shuffle(item)
>>> item
[5, 9, 7, 1, 3]
"""需求:生成随机验证码
大写字母 小写字母 数字
5位数的随机验证码
chr
random.choice
封装成一个函数,用户想生成几位就生成几位
"""
# 代码实现:
import random
n = int(input('需要几位验证码>>>:').strip())
def v_code():
code = ''
for i in range(n):
num = str(random.randint(0,9))
alf = chr(random.randint(65,90))
upper = chr(random.randint(97,122))
code += random.choice([num,alf,upper])
return code
res = v_code()
print(res)
os模块
os模块:跟操作系统打交道的模块
sys模块:跟python解释器打交道模块
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False 如果是文件夹也False
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.path.getsize(path) 返回path的大小 单位是字节
sys模块
sys模块是与python解释器交互的一个接口
# 常用方法
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0),错误退出sys.exit(1)
sys.version 获取Python解释程序的版本信息
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
'''执行结果
['D:/Python/Day17/test.py']
3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)]
['D:\Python\Day17', 'D:\Python', ...
win32
'''
序列化模块
什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。方便跨平台使用。
写入文件的数据必须是字符串;基于网络传输的数据必须是二进制
序列化:其他数据类型转成字符串的过程
反序列化:字符串转成其他数据类型
json
Json模块提供了四个功能:dumps、dump、loads、load
优点:所有的语言都支持json格式
缺点:支持的数据类型很少 字符串 列表 字典 整型 元组(转成列表) 布尔值
dumps:序列化 将其他数据类型转成json格式的字符串
loads:反序列化 将json格式的字符串转换成其他数据类型
区别:
如果你要处理的是文件而不是字符串,dumps和loads不能对文件夹读写
你可以使用 json.dump() 和 json.load() 来编码和解码JSON数据
# loads 和dumps
import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
#注意,json转换完的字符串类型的字典中的字符串是由""表示的
dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典
#注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型
print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
# dump 和load
# 写入 JSON 数据,转字符串并自动写入文件
with open('data.json', 'w') as f:
json.dump(data, f)
# 读取数据
with open('data.json', 'r') as f:
data = json.load(f)
pickle
优点:python所有的数据类型都支持
缺点:只支持python
subprocess模块
subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。
Popen方法
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
--args:表示要执行的命令。必须是一个字符串,字符串参数列表。
--stdin、stdout 和 stderr:子进程的标准输入、输出和错误。其值可以是 subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者 None。subprocess.PIPE 表示为子进程创建新的管道。subprocess.DEVNULL 表示使用 os.devnull。默认使用的是 None,表示什么都不做。另外,stderr 可以合并到 stdout 里一起输出。
--timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
--check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
--encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
--shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。