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
具名元组 例子

实现方式二:

typing的NameTuple

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中时间格式符

 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)
View Code

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的大小
os方法合集

六、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示例:

>>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'))

 

 

 

                                                

posted @ 2019-07-18 23:07  www.pu  Views(444)  Comments(0Edit  收藏  举报