一、collections模块
在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.1namedtuple(具名元祖)
简单理解就是具有名字的元祖。生成:可以使用名字来访问元素内容的tuple元祖
应用场景1:定位坐标
from collections import namedtuple
point=namedtuple('坐标',['x','y','z'])
p=point(1,2,4)
print(p.y)
注意第二个参数:既要用可以传可迭代参数;也可以传字符串(字符串之间要用空格隔开)
第一个是类名,第二个是类的各个字段的名字。后者可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串
point = namedtuple('坐标','x y z')
注意传值要与namedtuple匹配
p=point(1,2,4)
应用场景2:在线打牌
# card=namedtuple('扑克牌','colour number')
#可以写可迭代对象:
card=namedtuple('扑克牌',['colour','number'])
a=card('♥','A')
print(a)
print(a.colour)
#扑克牌(colour='♥', number='A')
#♥
应用场景3:记录城市信息
city=namedtuple('日本','name person size')
a=city('东京','B老师','D')
print(a)
print(a.size)
应用场景4:表示一个圆
circle=namedtuple('圆',('x','y','r'))
a=circle(20,30,50)
print(a)
1.2deque(双端队列)
1.2.1普通队列(导入import queue模块)
队列:先进先出(FIFO first in first out)
队列的几个方法:
生成队列对象:q=queue.Queue()
给队列增加值:q.put()
从队列中取值:q.get()
import queue
q=queue.Queue()# 生成队列对象
q.put(1)# 往队列中添加值
q.put(2)
print(q.get())# 朝队列要值
print(q.get())
当队列中的值去完了,程序会原地等待,直到你往队列中增加值为止
1.2.2双端队列(导入from collection import deque)
双端队列的增加值与取值方式:
1.增加值:
append、appendleft
2.取值
pop、popleft
from collections import deque
q=deque(['a','b','c'])
#增加值
q.appendleft('g')
print(q)
#弹出值
q.popleft()
print(q)
另外:队列不应该支持任意为止插值,虽然可以插值。
插值的方法:
q.insert(索引号,插入的内容)
三、OrderedDict(有序字典)
原先字典是“无序”
的。复习一个生成字典的方式:
(列表中套元祖)
d = dict([('a', 1), ('b', 2), ('c', 3)])
d # dict的Key是无序的
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序:
>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> od.keys() # 按照插入的Key的顺序返回
['z', 'y', 'x']
四、defaultdict(默认值字典)
defaultdict是Python内建dict类的一个子类,第一个参数为default_factory属性提供初始值,默认为None。它覆盖一个方法并添加一个可写实例变量。它的其他功能与dict相同,但会为一个不存在的键提供默认值,直接新建一个K即可。从而避免KeyError异常。
有如下值集合 [11,22,33,44,55,66,77,88,99,90],将所有大于66的值保存至字典的第一个key中,将小于66 的值保存至第二个key的值中。
4.1在字典中创建一个新的空列表,用来存在新增K对应的值
from collections import defaultdict
values = [11, 22, 33,44,55,66,77,88,99,90]
my_dict = defaultdict(list) # 后续该字典中新建的key对应的value默认就是列表
print(my_dict['aaa'])
for value in values:
if value>66:
my_dict['k1'].append(value)
else:
my_dict['k2'].append(value)
print(my_dict)
4.2defaultdict()新建一个
my_dict1 = defaultdict(int)
my_dict1['H']=2
print(my_dict1)
五、Counter(以字典形式计数)
Counter类的目的是s用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。
from collections import Counter
s='dfeaerfdsfeafeasfawef'
print(Counter(s))
六、时间模块
三种表现形式
1.时间戳(timestamp)
2.格式化时间(用来展示给人看的):Format String:1999-12-1
3.结构化时间((struct_time):(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
import time
print(time.strftime('%Y-%m-%d %X'))
%X等价于%H:%M:%S。
注意只有m和d是小写
print(time.strftime('%Y-%m-%d %H:%M:%S'))
打印几时几分
print(time.strftime('%H:%M'))
打印年月
print(time.strftime('%Y/%m'))
时间元组:localtime将一个时间戳转换为当前时区的struct_time
time.localtime()
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.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
七、datetime模块
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对象
timedelta对象 = 日期对象 +/- 日期对象
current_time = datetime.date.today() # 日期对象
timetel_t = datetime.timedelta(days=7) # timedelta对象
res1 = current_time+timetel_t # 日期对象
print(current_time - timetel_t)
print(res1-current_time)
小练习 计算今天距离今年过生日还有多少天
birth = datetime.datetime(2019,12,21,8,8,8)
current_time = datetime.datetime.today()
print(birth-current_time)
UTC时间
dt_today = datetime.datetime.today()
dt_now = datetime.datetime.now()
dt_utcnow = datetime.datetime.utcnow()
print(dt_utcnow,dt_now,dt_today)
八、random模块(随机模块)
import random
随机选取整数范围内的数字:randint
print(random.randint(1,6))
随机取0-1之间小数:random.random()
print(random.random())
随机从列表中取一个元素
import random
print(random.choice([1,2,3,4,5,6]))
shuffle将整个列表顺序打乱
res = [1,2,3,4,5,6]
random.shuffle(res) # 洗牌
print(res)
生成随机验证码(例题)
def outter(n):
code=''
for i in range(n):
upper_str=chr(random.randint(65,90))
low_str=chr(random.randint(97,122))
my_int=str(random.randint(0,9))
code += random.choice([upper_str,low_str,my_int])
return code
res=outter(5)
print(res)
九、os模块和sys模块
os模块:跟操作系统打交道的模块
sys模块:跟python解释器打交道模块
os.listdir(r'路径')。会将当前文件夹下所有文件展示出来
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())
import sys
将某个路径添加到系统环境变量中
sys.path.append()
sys.argv
获取在后面输入的值
获取用户输入选择功能
import sys
print(sys.argv) # 命令行启动文件 可以做身份的验证
if len(sys.argv) <= 1:
print('请输入用户名和密码')
else:
username = sys.argv[1]
password = sys.argv[2]
if username == 'wuxi' and password == '123':
print('欢迎使用')
# 当前这个py文件逻辑代码
else:
print('用户不存在 无法执行当前文件')
十、序列化模块
序列:字符串
序列化:其他数据类型转换成字符串的过程
写入文件的数据必须是字符串
基于网络传输的数据必须是二进制
序列化:其他数据类型转成字符串的过程
反序列化:字符串转成其他数据类型
json模块(******)
所有的语言都支持json格式
支持的数据类型很少 字符串 列表 字典 整型 元组(转成列表) 布尔值
pickle模块(****)
只支持python
python所有的数据类型都支持
1.import json
dumps和loads
在内存中做数据转换:
dumps 数据类型转成字符串 #序列化
loads 字符串转成数据类型 #反序列化
dump和load
直接将数据类型写入文件,直接从文件中读出数据类型
dump 数据类型写入文件 #序列化
load 从文件读出数据类型 #反序列化
2.pickle模块
1.支持在python中几乎所有的数据类型
2.dumps序列化的结果只能是字节
3.只能在python中使用
4.在和文件操作的时候,需要用rb,wb的模式打开文件
5.可以多次dump和load
import json
d = {"name":"jason"}
res = json.dumps(d) # json格式的字符串 必须是双引号
print(res,type(res))
#{"name": "jason"} <class 'str'>
res1 = json.loads(res)
print(res1,type(res1))
dump和load
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))
写入多次
import json
d={'name':'1'}
with open('userinfo','w',encoding='utf-8') as f:
json.dump(d,f) # 装字符串并自动写入文件
json.dump(d,f) # 装字符串并自动写入文件
#写入两次。结果是并排写{"name": "1"}{"name": "1"}
此时load不能讲其取出,会报错。因为是同一行,不能不知道从何处取
解决方法:用dumps序列化
with open('userinfo','w',encoding='utf-8') as f:
str_d=json.dumps(d)
f.write('%s
'%str_d)
读的步骤:用loads
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))
json中有中文:会出来二进制数
使用ensure_=ascill=False
d={'name':'侍玲玲'}
print(json.dumps(d))
十一、pickle模块
import pickle
d = {'name':'wuxi'}
res = pickle.dumps(d)
print(res) # 将对象直接转成二进制
res1 = pickle.loads(res)# 将对象还原成字典
print(res1,type(res1))
用pickle操作文件的时候 文件的打开模式必须是b模式
import pickle
d={'name':'sll'}
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
sub :子
process:进程
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'))