03 常用模块-collections (具名元组,计数器,有序字典等) 、时间模块、random、os、sys、序列化模块、subprocess模块
一、collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple: 生成可以使用名字来访问元素内容的tuple
2.deque: 双端队列,可以快速的从另外一侧追加和推出对象
3.Counter: 计数器,主要用来计数
4.OrderedDict: 有序字典
5.defaultdict: 带有默认值的字典
1. namedtuple 具名元组
具名元组:具有名称的元组
实现方式一:
# 想表示坐标点x为1 y为2 z为5 的坐标 from collections import namedtuple point = namedtuple('坐标',['x','y','z']) # 第二个参数既可以传可迭代对象如 列表 # point = namedtuple('坐标','x y z') # 也可以传字符串 但是字符串之间以空格隔开 p = point(1,2,5) # 注意元素的个数必须跟namedtuple第二个参数里面的值数量一致 print(p) # 坐标(x=1, y=2, z=5) print(p.x) # 1 print(p.y) # 2 print(p.z) # 5
from collections import namedtuple card = namedtuple('扑克牌','color number') # card1 = namedtuple('扑克牌',['color','number']) A = card('♠','A') print(A) #扑克牌(color='♠', number='A') print(A.color) # ♠ print(A.number) # A city = namedtuple('日本','name person size') c = city('东京','R老师','L') print(c) #日本(name='东京', person='R老师', size='L') print(c.name) #东京 print(c.person) #R老师 print(c.size) #L
实现方式二:
2.queue 队列(FIFO first in first out) 和 deque 双端队列
首先可以温习一下队列的知识:1.python自带的queue 2.进程模块封装的高级点的Queue
>>进程队列、python原生队列<<
queue队列 先进先出 (FIFO first in first out)
import queue q = queue.Queue() # 生成队列对象 q.put('first') # 往队列中添加值 q.put('second') q.put('third') print(q.get()) # first 朝队列要值 print(q.get()) #second print(q.get()) #third print(q.get()) # 如果队列中的值取完了 程序会在原地等待 直到从队列中拿到值才停止
deque 双端队列
虽然叫双端队列,但是和队列有区别,不是队列,不可以像队列一样支持进程间通讯
我理解其实是高级的list,方法上像list,如:append , appendleft, pop, popleft, clear, insert, reverse, remove, 索引取值
deque实现了列表的双向插入和删除操作提高效率,适合用于队列和栈:
# append
# appendleft
# pop
# popleft
from collections import deque q = deque(['a','b','c']) q.append(1) q.appendleft(2) print(q) #deque([2, 'a', 'b', 'c', 1]) print(q.pop()) # 1 print(q.popleft()) # 2 #了解一下 #队列不应该支持任意位置插值,只能在首尾插值(不能插队是吧),但是双向队列有个傻子方法,插入,乱插 from collections import deque q = deque(['a','b','c']) q.insert(1,'哈哈哈') # 特殊点:双端队列可以根据索引在任意位置插值 print(q) #deque(['a', '哈哈哈', 'b', 'c'])
3.OrderedDict 有序字典
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
:
normal_d = dict([('a',1),('b',2),('c',3)]) print(normal_d) #{'a': 1, 'b': 2, 'c': 3} #常规的dict字典是无序的 from collections import OrderedDict order_d = OrderedDict([('a',1),('b',2),('c',3)]) print(order_d) #OrderedDict([('a', 1), ('b', 2), ('c', 3)]) #如果到终端里用python2输出后会发现常规字典每次输出里面的键值对位置会变化,有序字典不会变
4. defaultdict 带有默认值的字典
有如下值集合 [
11
,
22
,
33
,
44
,
55
,
66
,
77
,
88
,
99
,
90.
..],将所有大于
66
的值保存至字典的第一个key中,将小于
66
的值保存至第二个key的值中。
即: {
'k1'
: 大于
66
,
'k2'
: 小于
66
}
from collections import defaultdict values = [11, 22, 33,44,55,66,77,88,99,90] my_dict = defaultdict(list) # 后续该字典中新建的key对应的value默认就是列表,括号里面写什么默认就是什么 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 my_dict = defaultdict(list) print(my_dict['aaa']) # [] my_dict1 = defaultdict(int) print(my_dict1['xxx']) # 0 # my_dict2 = defaultdict(bool) print(my_dict2['kkk']) # False my_dict3 = defaultdict(tuple) print(my_dict3['mmm']) #()
5.Counter 计数器 了解
Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。
#Counter
from collections import Counter s = 'abcdeabcdabcaba' res = Counter(s) print(res) #Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1}) #常规方法 s = 'abcdeabcdabcaba' d = {} for i in s: d[i] = s.count(i) print(d) #{'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1}
二、time模块
1.时间戳 time.time()
输出的是当前时间距离1970.00.00(unix诞生元年)的秒数
import time print(time.time()) #1563448982.512161
2.格式化时间 time.strftime()
inport time
print(time.strftime('%Y-%m-%d %H:%M:%S')) #2019-07-18 19:23:02 print(time.strftime('%Y-%m-%d %X')) #2019-07-18 19:23:02 %X等价于%H:%M:%S,没发现time模块支持毫秒,datetime可以
import time print(time.strftime('%Y-%m-%d')) #2019-07-18 print(time.strftime('%H:%M')) # 19:23 print(time.strftime('%Y/%m')) # 2019/07
%Y 四位数的年份表示(000-9999) %m 月份(01-12) %d 月内中的一天(0-31) %H 24小时制小时数(0-23) %I 12小时制小时数(01-12) %M 分钟数(00=59) %S 秒(00-59) %X 本地相应的时间表示 %X等价于%H:%M:%S %y 两位数的年份表示(00-99) %a 本地简化星期名称 %A 本地完整星期名称 %b 本地简化的月份名称 %B 本地完整的月份名称 %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366) %p 本地A.M.或P.M.的等价符 %U 一年中的星期数(00-53)星期天为星期的开始 %w 星期(0-6),星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始 %x 本地相应的日期表示 %Z 当前时区的名称 %% %号本身
python获取格式化时间到毫秒:
import time from datetime import datetime print(datetime.now().strftime('%Y%m%d%H%M%S%f')) time.sleep(0.1) # 不睡眠的话这些时间一样的,程序执行太快了 print(datetime.now().strftime('%Y/%m/%d %H/%M/%S.%f')) time.sleep(0.1) print(datetime.now().strftime('%Y-%m-%d- %H-%M-%S %f')) """ 20210928112105011409 2021/09/28 11/21/05.124992 2021-09-28- 11-21-05 234589 """
3.结构化时间 time.localtime()
共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
print(time.localtime()) #time.struct_time(tm_year=2019, tm_mon=7, tm_mday=18, tm_hour=19, tm_min=23, tm_sec=2, tm_wday=3, tm_yday=199, tm_isdst=0)
4.三种时间的转化 会用就行
时间戳和格式化时间不能直接转换,只能通过结构化时间间接转化
print(time.localtime(time.time())) #时间戳转结构化时间 res = time.localtime(time.time()) print(time.mktime(res)) #结构化时间转时间戳 print(time.strftime('%Y-%m',time.localtime())) #结构化时间转格式化时间 print(time.strptime(time.strftime('%Y-%m',time.localtime()),'%Y-%m')) #结构化时间转格式化时间再转回结构化时间
eg:时间戳-->结构化时间-->格式化时间
import time start_time, end_time = [1630771200000, 1631462400000] print(time.time()) # 1631606332.420453 python的时间戳:float类型的秒 # java的时间戳可能是int类型的毫秒,必须转化为python的时间戳:float类型的秒 start_time = float(int(start_time)/1000) end_time = float(int(end_time)/1000) print(start_time, end_time) #1630771200.0 1631462400.0 start_time = time.strftime('%Y-%m-%d', time.localtime(start_time)) end_time = time.strftime('%Y-%m-%d', time.localtime(end_time)) print(start_time, end_time) #2021-09-05 2021-09-13 print(start_time>end_time) # False 格式化时间支持比大小 print(type(start_time)) # <class 'str'>
eg: 中文时间转化为数字
import time from datetime import date, datetime, timedelta a = "10月10日17点18分20秒" # 加一个年份 a = str(datetime.today().year)+'年'+a # 2021年10月10日 # 转化为 结构化时间 b = time.strptime(a,'%Y年%m月%d日%H点%M分%S秒') #time.struct_time(tm_year=2021, tm_mon=10, tm_mday=10, tm_hour=17, tm_min=18, tm_sec=20, tm_wday=6, tm_yday=283, tm_isdst=-1) # 转化为 格式化时间 c = time.strftime('%Y-%m-%d',b) # 2021-10-10
5.时间转字符串
#结构化时间 --> %a %b %d %H:%M:%S %Y串 #time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串 >>>time.asctime(time.localtime(1500000000)) 'Fri Jul 14 10:40:00 2017' >>>time.asctime() 'Mon Jul 24 15:18:33 2017' #时间戳 --> %a %b %d %H:%M:%S %Y串 #time.ctime(时间戳) 如果不传参数,直接返回当前时间的格式化串 >>>time.ctime() 'Mon Jul 24 15:19:07 2017' >>>time.ctime(1500000000) 'Fri Jul 14 10:40:00 2017'
6.time.sleep(10) cpu睡10秒
三、datetime模块
1.获取当前时间
date:年月日 datetime:年月日 时分秒
from datetime import data, datetime, time, timedelta
date.today() # 2019-08-05 年月日
datetime.today() #2019-08-05 19:31:05.106413 年月日时分秒
datetime.now() #2019-08-05 19:31:05.106413
datetime.now().date() #2019-08-05 年月日
time(hour=16) #表示时间点,16点
next_time = datetime.combine(date=datetime.now.date(), time=time(hour=20)) #2019-08-05 20:00:00 组合时间
detal = next_time - datetime.now() #00:28:54
detal.total_seconds() # 转化成秒
res = date.today()
res1 = datetime.today() #这个也有类似res功能
print(res.year) #2019
print(res.month) #7
print(res.day) #18
print(res.weekday()) #3 0-6表示星期 0表示周一
print(res.isoweekday()) #4 1-7表示星期 7就是周日
2. 日期 加减
日期对象 = 日期对象 +/- timedelta对象
timedelta对象 = 日期对象 +/- 日期对象
from datetime import datetime, date, timedelta current_time = date.today() # 日期对象 timetel_t = timedelta(days=7) # timedelta对象,表示时间段,时分秒都可表示 res1 = current_time+timetel_t # 日期对象
res2 = current_time - timetel_t
print(current_time) #2019-07-18 print(timetel_t) #7 days, 0:00:00 print(res2) #2019-07-11 print(timetel_t) #7 days, 0:00:00
# 小练习 计算今天距离今年过生日还有多少天
birth = datetime.datetime(2019,12,21,8,8,8)
current_time = datetime.datetime.today()
print(birth-current_time) #155 days, 11:14:29.983946
2021-01-01 形式加减
import datetime time_str = '2021-07-01' start_time = datetime.datetime.strptime(time_str, '%Y-%m-%d').date() current_time = datetime.datetime.now().date() print(start_time) # 2021-07-01 print(current_time) # 2021-07-07 print((current_time-start_time).days) # 6
3.UTC时间
today = now = utc +8h
dt_today = datetime.datetime.today() #2019-07-18 20:42:46.234774 dt_now = datetime.datetime.now() #2019-07-18 20:42:46.234774 dt_utcnow = datetime.datetime.utcnow() #2019-07-18 12:45:14.384247 print(dt_utcnow) print(dt_now) print(dt_today)
4.ISO时间格式转换
import datetime,time # datetime时间对象 tim1 = datetime.datetime.fromtimestamp(time.time() + 10) # 2020-09-25 17:49:52.187648 # 转换为ISO时间格式,seq是拼接符号默认为T tim1.isoformat() # 2020-09-25T17:49:52.187648 tim1.isoformat(timespec='minutes') # 2020-09-25T17:49 是字符串 tim1.isoformat(sep=' ', timespec='minutes') # 2020-09-25 17:49 tim1.isoformat(sep=' ', timespec='seconds') # 2020-09-25 17:49:52
四、random模块 随机模块
import random #random.randint() 随机数 print(random.randint(1,6)) # 随机取一个你提供的整数范围内的数字 包含首尾 #random.random() 随机小数 print(random.random()) # 随机取0-1之间小数 #random.choice() 摇号 print(random.choice([1,2,3,4,5,6])) # 摇号 随机从列表中取一个元素 #random.shuffle() 洗牌 res = [1,2,3,4,5,6] random.shuffle(res) # 洗牌 打乱列表顺序
random.sample() 从固定或指定内容中随机出指定长度列表
if __name__ == '__main__': import random str_1 = 'afdsggfgdhdhhd' data1 = random.sample(str_1,5) # 从指定范围内取出指定个数的元素,组成列表 data2 = "".join(random.sample(str_1,5)) print(data1) # ['g', 'f', 'd', 'h', 'g'] print(data2) # ghsha 可做验证码,随机验证码时不要用0/o,1/i data3 = random.sample(range(1,10),5) list1 = [1,2,3,4,5,6,7] data4 = random.sample(list1,5) print(data3) # [6, 1, 5, 4, 3] print(data4) # [2, 1, 3, 5, 7]
生成一个随机验证码,包含大写小写和数字(******)
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 get_code(n)
五、os模块 操作系统打交道
#前提 执行文件和老师们的作品文件同级 import os BASE_DIR = os.path.dirname(__file__) #返回上层主目录 MOVIE_DIR = os.path.join(BASE_DIR,'老师们的作品') #拼接路经 将作品目录地址添加到系统环境变量中 movie_list = os.listdir(MOVIE_DIR) #将当前路径下所有文件的文件名保存到一个列表中,打印列表出来
if not os.path.isdir(path): #(绝对路径),路径存在并且是目录时才会返回(不如exists)
os.mkdir(path) #创建文件夹
while True: for i,j in enumerate(movie_list,1): #从1开始增加用户体验
print(i,j) choice = input('你想看谁的啊(今日热搜:tank老师)>>>:').strip()
if choice.isdigit():
choice = int(choice)
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.remove(文件夹名字) #移除文件夹
os.rename(老名字,新名字) #给文件夹换名字
os.mkdir('tank老师精选') # 自动创建文件夹
os.makedirs()#'a\b\c' 递归创建 不存在就创建,有几级就创建几个,例如b和c都不存在就先创建并在创建c,如果是mkdir多级文件不存在会爆炸
print(os.path.exists(r'D:\Python项目\day16\rion老师精选')) True# (绝对路径)只要路径存在,不管是目录还是文件都会返回(比isdir强大一点)
print(os.path.exists(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) True# 判断文件是否存在
print(os.path.isfile(r'D:\Python项目\day16\tank老师精选')) False # 只能判断文件 不能判断文件夹
print(os.path.isfile(r'D:\Python项目\day16\老师们的作品\tank老师.txt')) True# 只能判断文件 不能判断文件夹
os.rmdir(r'D:\Python项目\day16\老师们的作品') # 只能删空文件夹
print(os.getcwd()) #获取当前目录
print(os.chdir(r'D:\Python项目\day16\老师们的作品')) # 切换当前所在的目录 cd
# 获取文件大小
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())) #字符长度
os.makedirs('dirname1/dirname2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","newname") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.system("bash command") 运行shell命令,直接显示 os.popen("bash command).read() 运行shell命令,获取执行结果 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.path os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 os.path.getsize(path) 返回path的大小
六、sys模块 py解释器打交道 了解
sye.path #是一个列表 系统环境变量 第一个值就是执行文件所在的文件夹
sys.path.append() # 将某个路径添加到系统的环境变量中
sys.getsizeof(p) #查看p的内存字节大小
sys.version #查看python版本
sys.argv # 命令行启动文件 可以做身份的验证 exit() #退出解释器 import sys 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('用户不存在 无法执行当前文件')
异常处理会用到
import sys try: sys.exit(1) except SystemExit as e: print(e)
七、序列化模块
1.原生json模块
1. 序列:字符串 序列化:其他数据类型转成字符串的过程 反序列化:字符串转成其他数据类型 2.写入文件的数据必须是字符串 基于网络传输的数据必须是二进制,也是字符串 3.json模块(******) 所有的语言都支持json格式 支持的数据类型很少 字符串 列表 字典 整型 元组(转成列表) 布尔值 pickle模块(****) 只支持python python所有的数据类型都支持
1.json模块 (******)
dumps:序列化 将其他数据类型转成json格式的字符串
loads:反序列化 将json格式的字符串转换成其他数据类型
dump:序列化 要结合文件使用
load:反序列化 要结合文件使用
# dumps loads
import json d = {"name":"jason"} print(d) #{'name': 'jason'} #序列化 res = json.dumps(d) # json格式的字符串 必须是双引号 >>>: '{"name": "jason"}' print(res,type(res)) #{"name": "jason"} <class 'str'> #反序列化 res1 = json.loads(res) print(res1,type(res1)) #{'name': 'jason'} <class 'dict'>
#元祖转字典
t = (1,2,3,4)
print(json.dumps(t)) #[1, 2, 3, 4]
#汉字强制不转码
d1 = {'name':'朱志坚'}
print(json.dumps(d1,ensure_ascii=False)) #{"name": "朱志坚"} #默认为True,将汉字转化为编码,修改后,汉子还是汉字保存
#dump load import json 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)) #{'name': 'jason'} <class 'dict'>
import json d = {"name":"jason"} # 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))
2.将字典数据保存成json文件
import json import os class JsonConf: '''json配置文件类''' @staticmethod def store(data): with open("config.json", 'w') as json_file: json_file.write(json.dumps(data, indent=4)) json_file.flush() @staticmethod def load(): if not os.path.exists('config.json'): # 文件不存在就建一个空的 with open("config.json", 'w') as json_file: pass # 只修改不删除kv with open('config.json') as json_file: try: data = json.load(json_file) except: data = {} return data @staticmethod def set(data_dict): """更新config.json文件,不存在kv的新增,存在且相同的kv修改更新 """ json_obj = JsonConf.load() for key in data_dict: json_obj[key] = data_dict[key] JsonConf.store(json_obj) # print(json.dumps(json_obj, indent=4)) if __name__ == '__main__': dic = {'01':1,'02':2,'03':3,'04':4} JsonConf().set(dic)
3.pickle模块(****)
#dumps loads import pickle d = {'name':'jason'} #序列化 res = pickle.dumps(d) # 将对象直接转成二进制 print(pickle.dumps(d)) #b'\x80\x03}q\x00X\x04\x00\x00\x00nameq\x01X\x05\x00\x00\x00jasonq\x02s.' #反序列化 res1 = pickle.loads(res) print(res1,type(res1)) #{'name': 'jason'} <class 'dict'>
#dump load 用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)) #{'name': 'jason'} <class 'dict'>
2.高性能序列化 ujson
正常情况下,需要序列化/反序列化的数据不大的情况下,原生json和其他序列化模块差别不大,当数据量很大的情况下,差别就会很明显,一下为ujson示例:
安装:
python -m pip install ujson
通过以下代码可以看出,在数据还比较简单情况下,一百万条数据序列化性能差三倍,如果是复杂数据的话差别将会很大
还有其他几种高性能序列化模块,参考这里
代码演示:
# -*- coding: utf-8 -*- import json import ujson import time def cost_time(func): def inner(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) stop_time = time.time() print(stop_time - start_time) return result return inner a = {k:v for k,v in enumerate(range(1, 1000000))} @cost_time def json_dumps(obj): return json.dumps(obj) @cost_time def json_loads(obj): return json.loads(obj) @cost_time def ujson_dumps(obj): return ujson.dumps(obj) @cost_time def ujson_loads(obj): return ujson.loads(obj) r1 = json_dumps(a) r2 = ujson_dumps(a) print(r1 == r2) print('序列化后原生json比ujson大:',len(r1) - len(r2)) d1 = json_loads(r1) d2 = ujson_loads(r2) print(d1 == d2) print(len(d1)) print(len(d2)) """ 0.40663623809814453 0.12857413291931152 False 序列化后原生json比ujson大: 1999997 0.34185290336608887 0.16146421432495117 True 999999 999999 """
八、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'))