random 模块
随机小数
random
uniform
随机整数
- randint
- randrange
随机抽取
choice
sample
打乱顺序
shuffle
random.random() 生成: 0<n<1.0
uniform(x,y) 一定范围的随机浮点数 (包左包右)
random.uniform(x,y)
randint(x,y) 随机整数 (包左包右)
randrange(x,y,z) 随机整数 (包左不包右)
random.randrange(10,100,4) #输出为 10 到 100 内以 4 递增的序列 [10,14,18,22...]
choice(seq) 从序列中获取一个随机元素, 参数 seq 表示有序类型, 并不是一种特定类型, 泛指 list tuple 字符串等
- import random
- random.choice(range(10)) #输出 0 到 10 内随机整数
- random.choice(range(10,100,2)) #输出随机值 [10,12,14,16...]
- random.choice("I love python") #输出随机字符 I,o,v,p,y...
- random.choice(("I love python")) #同上
- random.choice(["I love python"]) #输出 "I love python"
- random.choice("I","love","python") #Error
- random.choice(("I","love","python")) #输出随机字符串 "I","love","python"
- random.choice(["I","love","python"]) #输出随机字符串 "I","love","python"
shuffle(list) 用于将一个列表中的元素打乱
sample() 从指定序列中随机获取 k 个元素作为一个片段返回, sample 不会改变原有序列
- a='1232445566'
- b=[1,2,3,4,4,5]
- print(random.sample(b,2))
- print(random.sample(a,2))
time 时间模块
time.strftime('%Y-%m-%d %H:%M:%S')
sys 模块
sys 是与 python 解释器相关的
sys.path 寻找文件的路径
sys.modules 导入多少路径
在编译器不能运行
- name=sys.argv[1] # 有点类似 input() 不过 input 是阻塞的
- pwd=sys.argv[2]
- if name='alex' and pwd =='alex3714':
- print('执行以下代码')
- else:
- exit()
os 模块
- print(os.getcwd()) # 在哪个地方执行这个文件, getcwd 的结果就是哪个路径
- removedirs
递归向上删除文件夹, 只要删除当前目录之后, 发现上一级目录也为空了, 就把上一级目录删除
如果发现上一级目录有其他文件, 就停止
os.listdir() (重要) 列出指定目录下的所有文件和子目录, 包括隐藏文件, 并以列表方法打印
print(os.path.dirname(os.path.dirname(__file__)))# 上一级再上一级目录, 也就是工作区
序列化
得到一个字符串的结果, 过程就叫序列化
字典 / 列表 / 数字 / 对象 - 序列化 --> 字符串
为什么要序列化
要把内容写入文件
网络传输数据
eval 不能随便用
- dump dumps load loads
- import JSON
- dic={'aaa':'bbb','ccc':'ddd'}
- str_dic=JSON.dumps(dic) # 序列化
- print(dic)
- print(str_dic,type(str_dic))
- with open('json_dump','w') as f:
- # f.write(str_dic) # 反序列化
- JSON.dump(dic,f)
- ret=JSON.loads(str_dic) # 反序列化
- print(ret,type(ret))
- with open('json_dump1') as f:
- print(type(JSON.load(f)))
JSON 的限制
JSON 格式的 key 必须是字符串数据类型, 如果是数字为 key 那么 dump 之后会强行转成字符串数据类型
JSON 格式中的字符串只能是双引号
JSON 是否支持元祖, 对元组做 value 的字典会把元组强制转换成列表
- dic={
- 'abc':(1,2,3)
- }
- str_dic=JSON.dumps(dic)
- print(str_dic)
JSON 是否支持元组做 key, 会报错
pickle
pickle 支持几乎所有对象
- dic={
- 1:(12,3,4),('a','b'):4
- }
- pic_dic=pickle.dumps(dic)# 序列化 看不见 bytes 类型
- print(pic_dic)
- new_dic=pickle.loads(pic_dic)# 反序列化
对于对象的序列化需要这个对象对应的类在内存中
dump 的结果是 bytes, dump 用的 f 文件句柄需要以 wb 的形式打开, load 所用的 f 是'rb'模式
- with open('pickle_demo','wb') as f:
- pickle.dump(alex,f)
- with open('pickle_demo','rb') as f:
- wangcai=pickle.load(f)
- print(wangcai.name)
- with open('pickle_demo','rb') as f:
- while True: # 不知道循环几次不能用 for 用 while
- try:
- print(pickle.load(f))
- except EOFError:
- break
- import shelve # 不建议使用
- # 存值
- f=shelve.open("shelve_demo")
- f['key']={'k1':(1,2,3),'k2':'v2'}
- f.close()
- # 取值
- f=shelve.open('shelve_demo')
- content=f['key']
- f.close()
- print(content)
加密 md5 sha1
- # hashlib.md5()
- # hashlib.sha1()
- #md5 是一个算法, 32 位的字符串 , 每个字符串是一个十六进制
- # sha1 也是一个算法, 40 位的字符串, 每个字符都是一个十六进制
- # 算法相对复杂 计算速度也慢
- md5_obj=hashlib.md5()
- md5_obj.update(s.encode('utf-8'))
- res=md5_obj.hexdigest()
- print(res,len(res),type(res))
- # 数据库 撞库
- # 加盐
- md5_obj=hashlib.md5("加盐".encode('utf-8'))
- md5_obj.update(s.encode('utf-8'))
- # 动态加盐
- username=input('username:')
- passwd=input('passwd')
- md5obj=hashlib.md5(username.encode('utf-8'))
- md5obj.update(passwd.encode('utf-8'))
- print(md5obj.hexdigest())
configparser 模块
logging 模块
功能
日志格式的规范
操作的简化
日志的分级管理
logging 模块的使用
- logging.basicConfig(level=logging.DEBUG) #级别
- logging.debug('debug message') #调试模式
- logging.info('info message') # 基础信息
- logging.warning('warning message')# 警告
- logging.error('error message') # 错误
- logging.critical('critical message') # 严重错误
- basicConfig
不能将一个 log 信息既能输出到屏幕上有输出到文件上
- # logger 对象的形式来操作日志文件
- # 创建一个 logger 对象
- logger=logging.getLogger()
- # 创建一个文件管理操作符
- fh=logging.FileHandler()
- # 创建一个屏幕管理操作符
- sh=logging.StreamHandler()
- # 创建一个日志输出的格式
- format1=logging.Formatter('%(asctime)s-%(name)s-%(lecelname))
- # 文件管理操作符 绑定一个格式
- sh.setFormatter(format1)
- # 屏幕管理操作符 绑定一个格式
- # logger 对象 绑定 文件管理操作符
- # logger 对象 绑定 屏幕管理操作符
网络编程
由于不同机器上的程序要通信, 才产生了网络
server 服务端
client 客户端
b/s 架构 ----> 统一入口 (解耦分支)
b/s 和 c/s 架构的关系
b/s 架构师 c/s 架构的一种
网关的概念
局域网中的机器想要访问局域网外的机器, 需要通过网关
端口 找到的程序
在计算机上, 没一个需要网络通信的程序, 都会开一个端口
在同一时间只会有一个程序占用一个端口
不可能在同一时间有两个程序占用同一个端口
端口的范围 0-65545, 一般情况下 8000 之后的端口
ip 确定唯一一台机器
端口 --- 确定唯一的一个程序
ip + 端口 找到唯一的一台机器上的唯一的一个程序
tcp 协议和 udp 协议
这个全双工的通信将占用两个计算机之间的通信线路, 直到它被一方或双方关闭为止
arp 地址 通过 ip 找 Mac
ip 协议属于网络 osi 七层协议中的哪一层, 网络层
tcp 协议 udp 协议属于传输层
arp 协议 属于数据链路层
黏包问题 不知道客户端发送的数据的长度
大文件的传输一定要按照字节读, 每一次读固定的字节
> 实现一个大文件的上传或者下载 ---
server 端
- import JSON
- import socket
- import struct
- sk=socket.socket()
- sk.bind(('127.0.0.1',8090))
- sk.listen()
- buffer=1024
- conn,addr=sk.accept()# 接受
- head_len=conn.recv(4)
- head_len=struct.unpack('i',head_len)[0]
- json_head=conn.recv(head_len).decode('utf-8')
- head=JSON.loads(json_head)
- filesize=head['filesize']
- with open(head['filename'],'wb') as f:
- while filesize:
- if filesize>=buffer:
- content=conn.recv(buffer)
- f.write(content)
- filesize-=buffer
- else:
- content=conn.recv(filesize)
- f.write(content)
- filesize=0
- break
- conn.close()
- sk.close()
client 端
- import JSON
- import socket
- import os
- import struct
- buffer = 1024
- sk = socket.socket()
- sk.connect(('127.0.0.1', 8090))
- head = {# 发送文件
- 'filepath': r'文件路径',
- 'filename': r'文件名',
- 'filesize': None
- }
- file_path = os.path.join(head['filepath'], head['filename'])
- filesize = os.path.getsize(file_path)
- head['filesize'] = filesize
- json_head = JSON.dumps(head) # 字典转成字符串
- bytes_head = json_head.encode('utf-8') # 字符串转成 bytes
- print(json_head)
- print(bytes_head)
- head_len = len(bytes_head)# 计算 head 长度
- pack_len = struct.pack('i', head_len)
- sk.send(pack_len) # 先发报头的长度
- sk.send(bytes_head)
- with open(file_path, 'rb') as f:
- while filesize:
- if filesize> buffer:
- content = f.read(buffer) # 每次读出来的内鹅绒
- sk.send(content)
- filesize -= buffer
- else:
- content = f.read(filesize)
- f.read(content)
- break
- # 解决黏包问题
- # 为什么会会出现黏包现象
- # 首先 只有在 TCP 协议中才会出现黏包现象
- # 是因为 TCP 协议是面向流的协议
- # 在发送的数据传输的过程中还有缓存机制避免数据丢失
- # 因此在连续发送小数据的时候, 以及接受大小不符的时候都容易出现黏包现象
- # 本质还是因为我们在接受数据的时候不知道发送的数据的长短
- # 解决黏包问题
- # 在传输大量数据之前先告诉接受端要发送的数据大小
- # 如果想更漂亮的解决问题, 可以通过 struct 模块来定制协议
- # struct 模块
- # pack unpack
- # 模式: 'i'
- # pack 之后的长度: 4 个字节
- #unpack 之后拿到的数据是一个元组: 元组的第一个元素才是 pack 的值
- ```
来源: https://www.cnblogs.com/fangdongdemao/p/9984727.html