collections模块、时间模块、random模块、os模块、sys模块、序列化模块、subprocess模块
一、collections模块
1、其他数据类型
在内置数据类型(str、dict、list、tuple、set)的基础上,collections模块还提供了了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict。
2、namedtuple(具名元组)
①、用具名元组表示一个点坐标
from collections import namedtuple Point = namedtuple('Point',['x','y']) p = Point(1, 2) print(p) # 输出 Point(x=1, y=2)
②、用具名元组记录一个城市的信息
from collections import namedtuple City = namedtuple('City','name country population coordinates') # 第一个是类名,第二个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串 tokyo = City('Tokyo','JP',36.933,(35.689722,139.691667)) print(tokyo) # 输出 City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))
③、格式:namedtuple('名称',[属性list])
3、deque(双端队列)
①、使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适用于队列和栈。
②、qeque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效的往头部添加或删除元素。
from collections import deque q = deque(['a','b','c']) q.pop() q.append('x') q.popleft() q.appendleft('y') print(q) # 输出 deque(['y', 'b', 'x'])
③、deque还支持insert()方法,可以在任意位置插值
from collections import deque q = deque(['a','b','c']) q.insert(1,'x') print(q) # 输出 deque(['a', 'x', 'b', 'c'])
④、queue 队列
import queue q = queue.Queue() # 创建一个队列对象 q.put(1) # 往队列里面放值 q.get() # 取出队列里面的值 q.get() # 队列中无值可取,程序会在原地等待
4、OrderedDict(有序列表)
使用dict时,key是无序的,在对dict做迭代时,我们无法确定key的顺序,如果要保持key的顺序,可以用OrderedDict
from collections import OrderedDict d = dict([('a',1),('b',2),('c',3)]) print(d) od = OrderedDict([('a',1),('b',2),('c',3)]) print(od) # python2中结果 >>> d {'a': 1, 'c': 3, 'b': 2} >>> od OrderedDict([('a', 1), ('b', 2), ('c', 3)]) # Python3中结果 >>> d {'a': 1, 'b': 2, 'c': 3} >>> od OrderedDict([('a', 1), ('b', 2), ('c', 3)]) # python3对列表做了优化,使他看上去是有序的
5、defaultdict(默认值字典)
①、有如下值[11, 22, 33, 44, 55, 66, 77, 88, 99, 90],将所有大于66的值保存至字典的第一个key中,将小于66的值保存至第二个key的值中
# 原生字典解决方案 values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = {} for value in values: if value>66: if my_dict.__contains__('k1'): my_dict['k1'].append(value) else: my_dict['k1'] = [value] else: if my_dict.__contains__('k2'): my_dict['k2'].append(value) else: my_dict['k2'] = [value] print(my_dict) # 输出 {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]} # defaultdict解决方案 from collections import defaultdict values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = defaultdict(list) # 该字典新增的键对应的值是一个空列表 for value in values: if value>66: my_dict['k1'].append(value) else: my_dict['k2'].append(value) print(my_dict) # 输出 defaultdict(<class 'list'>, {'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]})
②、使用dict时,如果引用的key不存在就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict
from collections import defaultdict dd = defaultdict(lambda: 'N/A') dd['key1'] = 'abc' print(dd['key1']) print(dd['key2']) # 输出 abc N/A # key存在时返回key的值,key不存在时返回你设置的默认值
6、Counter(计数)
Counter类的目的是用来跟踪值出现的次数,他是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的integer(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
from collections import Counter c = Counter('abcdeabcdabcaba') print(c) # 输出 Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
二、时间模块
1、表示时间的三种方式
①、时间戳(timestamp):表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。
②、格式化的时间字符串(format string):1999-12-06
③、元组(struct_time):struct_time元组中共有9个元素(年,月,日,时,分,秒,一年中第几周,一年中的几天等)
2、import time 导入时间模块
3、time.time()返回时间戳,time.sleep(n)使程序暂停n秒
4、时间字符串
import time print(time.strftime("%Y-%m-%d %X")) print(time.strftime("%Y-%m-%d %H-%M-%S")) # 输出 2019-07-18 22:12:55 2019-07-18 22-12-55
5、时间元组:localtime将一个时间戳转换为当前时区的struct_time
import time print(time.localtime()) # 输出 time.struct_time(tm_year=2019, tm_mon=7, tm_mday=18, tm_hour=22, tm_min=21, tm_sec=22, tm_wday=3, tm_yday=199, tm_isdst=0)
6、时间戳是计算机能够识别的时间;时间字符串是人能够看懂的时间;元组则是用来操作时间的
7、几种格式之间的转换
8、datatime模块
import datetime # 自定义日期 res = datetime.date(2019, 7, 15) print(res) # 2019-07-15 # 获取本地时间 # 年月日(****) now_date = datetime.date.today() print(now_date) # 2019-07-01 # 年月日时分秒(****) now_time = datetime.datetime.today() print(now_time) # 2019-07-01 17:46:08.214170 # 无论是年月日,还是年月日时分秒对象都可以调用以下方法获取针对性的数据 # 以datetime对象举例 print(now_time.year) # 获取年份2019 print(now_time.month) # 获取月份7 print(now_time.day) # 获取日1 print(now_time.weekday()) # 获取星期(weekday星期是0-6) 0表示周一 print(now_time.isoweekday()) # 获取星期(weekday星期是1-7) 1表示周一 # timedelta对象(****) # 可以对时间进行运算操作 import datetime # 获得本地日期 年月日 tday = datetime.date.today() # 定义操作时间 day=7 也就是可以对另一个时间对象加7天或者减少7点 tdelta = datetime.timedelta(days=7) # 打印今天的日期 print('今天的日期:{}'.format(tday)) # 2019-07-01 # 打印七天后的日期 print('从今天向后推7天:{}'.format(tday + tdelta)) # 2019-07-08 # 总结:日期对象与timedelta之间的关系
三、random模块
1、几种方法
print(random.randint(1,6)) #随机取一个你提供的整数范围内的数字,包含首尾 print(random.random()) # 随机取0-1之间的浮点数 print(random.choice([1, 2, 3, 4, 5, 6])) # 摇号 随机从列表中取一个元素 res = [1, 2, 3, 4, 5, 6] random.shuffle(res) print(res) # 洗牌
2、生成随机验证码
'''''' import random ''' 随机n位验证码 由大写字母,小写字母,数字组成,每种的个数不限 封装成一个函数,用户想生成几位就生成几位 ''' def get_code(n): code = '' for i in range(n): # 生成随机的大写字母,小写字母,数字 upper_str = chr(random.randint(65, 90)) # (****) lower_str = chr(random.randint(97, 122)) #(****) random_int = str(random.randint(0, 9)) # 从上面三个中随机选择一个作为随机验证码的某一位 code += random.choice([upper_str,lower_str,random_int]) return code res = get_code(4) print(res)
四、os模块
1、os模块是和操作系统打交道的模块
import os BASE_DIR = os.path.dirname(__file__) MOVIE_DIR = os.path.join(BASE_DIR,'老师们的作品') movie_list = os.listdir(MOVIE_DIR) while True: for i,j in enumerate(movie_list,1): print(i,j) choice = input('你想看谁的啊(今日热搜:tank老师)>>>:').strip() if choice.isdigit(): # 判断用户输入的是否是纯数字 choice = int(choice) # 传成int类型 if choice in range(1,len(movie_list)+1): # 判断是否在列表元素个数范围内 # 获取用户想要看的文件名 target_file = movie_list[choice-1] # 拼接文件绝对路径 target_path = os.path.join(MOVIE_DIR,target_file) with open(target_path,'r',encoding='utf-8') as f: print(f.read()) os.mkdir('tank老师精选') # 自动创建文件夹 print(os.path.exists(r'D:\Python项目\day16\rion老师精选')) # 判断文件是否存在 print(os.path.exists(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) # 判断文件是否存在 print(os.path.isfile(r'D:\Python项目\day16\tank老师精选')) # 只能判断文件 不能判断文件夹 print(os.path.isfile(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) # 只能判断文件 不能判断文件夹 os.rmdir(r'D:\Python项目\day16\老师们的作品') # 只能删空文件夹 print(os.getcwd()) print(os.chdir(r'D:\Python项目\day16\老师们的作品')) # 切换当前所在的目录 print(os.getcwd()) # 获取文件大小 print(os.path.getsize(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) # 字节大小 with open(r'D:\Python项目\day16\老师们的作品\tank老师.txt',encoding='utf-8') as f: print(len(f.read()))
2、常用方法
os.path.dirname(__file__) # 返回该文件所在文件夹的路径 os.listdir(path) # 返回一个列表,列表中的元素就是path路径下所有的文件名 os.path.join(BASE_DIR,target_file) # 拼接路径 os.path.exists() # 判断文件是否存在 os.path.isfile() # 只能判断文件 os.mkdir() # 创建文件夹 os.rmdir() # 删除空文件夹 os.getcwd() # 获取当前所在路径 os.chdir()切换路径,类似于cd命令 os.path.getsize() # 获取文件大小 os.remove() # 删除文件 os.rename() # 重命名
五、sys模块
import sys # sys.path.append() # 将某个路径添加到系统的环境变量中 # print(sys.platform) # print(sys.version) # python解释器的版本 print(sys.argv) # 命令行启动文件 可以做身份的验证 if len(sys.argv) <= 1: print('请输入用户名和密码') else: username = sys.argv[1] password = sys.argv[2] if username == 'jason' and password == '123': print('欢迎使用') # 当前这个py文件逻辑代码 else: print('用户不存在 无法执行当前文件')
sys.path
# 是一个列表,系统的环境变量,列表的第一个值就是执行文件所在的文件夹路径
sys.path.append()
# 往环境变量里添加路径
sys.argv()
# 是一个列表,列表中的每一个元素就是位于Python命令之后的一个个值
# 可以用于设置当前文件的权限
六、序列化模块
""" 序列化 序列:字符串 序列化:其他数据类型转换成字符串的过程 序列化的优点:
1.方便存储
2.网络传输
写入文件的数据必须是字符串 基于网络传输的数据必须是二进制 序列化:其他数据类型转成字符串的过程 反序列化:字符串转成其他数据类型 json模块(******) 所有的语言都支持json格式 支持的数据类型很少 字符串 列表 字典 整型 元组(转成列表) 布尔值 pickle模块(****) 只支持python python所有的数据类型都支持
pickle序列化之后的结果是一个二进制数据(bytes类型),所以文件的打开模式必须是b模式 import json """ dumps:序列化 将其他数据类型转成json格式的字符串 loads:反序列化 将json格式的字符串转换成其他数据类型 dumps和loads只能接收1个参数:待序列化的字符串
json.dumps()指定ensure_ascii=False参数时可以使序列化后的中文字符正常显示
dump
load
dump可以接收两个参数,第一个是待序列化的字符串,第二个是文件对象,他可以将序列化后的字符串自动写入文件 """ d = {"name":"jason"} print(d) res = json.dumps(d) # json格式的字符串 必须是双引号 >>>: '{"name": "jason"}' print(res,type(res)) res1 = json.loads(res) print(res1,type(res1)) d = {"name":"jason"} with open('userinfo','w',encoding='utf-8') as f: json.dump(d,f) # 装字符串并自动写入文件 with open('userinfo','r',encoding='utf-8') as f: res = json.load(f) print(res,type(res)) with open('userinfo','w',encoding='utf-8') as f: json.dump(d,f) # 装字符串并自动写入文件 json.dump(d,f) # 装字符串并自动写入文件 with open('userinfo','r',encoding='utf-8') as f: res1 = json.load(f) # 不能够多次反序列化 res2 = json.load(f) print(res1,type(res1)) print(res2,type(res2)) with open('userinfo','w',encoding='utf-8') as f: json_str = json.dumps(d) json_str1 = json.dumps(d) f.write('%s\n'%json_str) f.write('%s\n'%json_str1) with open('userinfo','r',encoding='utf-8') as f: for line in f: res = json.loads(line) print(res,type(res)) t = (1,2,3,4) print(json.dumps(t)) d1 = {'name':'朱志坚'} print(json.dumps(d1,ensure_ascii=False))
pickle import pickle d = {'name':'jason'} res = pickle.dumps(d) # 将对象直接转成二进制 print(pickle.dumps(d)) res1 = pickle.loads(res) print(res1,type(res1)) """ 用pickle操作文件的时候 文件的打开模式必须是b模式 """ with open('userinfo_1','wb') as f: pickle.dump(d,f) with open('userinfo_1','rb') as f: res = pickle.load(f) print(res,type(res))
七、subprocess模块
""" 1.用户通过网络连接上了你的这台电脑 2.用户输入相应的命令 基于网络发送给了你这台电脑上某个程序 3.获取用户命令 里面subprocess执行该用户命令 4.将执行结果再基于网络发送给用户 这样就实现 用户远程操作你这台电脑的操作 """ while True: cmd = input('cmd>>>:').strip() import subprocess obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) # print(obj) print('正确命令返回的结果stdout',obj.stdout.read().decode('gbk')) print('错误命令返回的提示信息stderr',obj.stderr.read().decode('gbk'))
import subprocess
sub_obj = subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
print(sub_obj.stdout.read()) # 直接拿到的是一个二进制数据(该二进制的编码是参考执行该命令计算机的操作系统默认编码)
print(sub_obj.stdout.read().decode('gbk')) # 直接拿到的是一个二进制数据(该二进制的编码是参考执行该命令计算机的操作系统默认编码) windows