json&pickle模块
1、什么是序列化 & 反序列化
内存中的数据类型--- -> 序列化--- -> 特定的格式(json格式或者pickle格式)
内存中的数据类型 < ----反序列化 < ----特定的格式(json格式或者pickle格式)
土办法:
{'aaa': 111}-- -> 序列化str({'aaa': 111})---- -> "{'aaa':111}"
{'aaa': 111} < ---反序列化eval("{'aaa':111}") < -----"{'aaa':111}"
2、为何要序列化
序列化得到结果 = >特定的格式的内容有两种用途
1、可用于存储 =》用于存档
2、传输给其他平台使用 =》跨平台数据交互
python java
列表 特定的格式 数组
强调:
针对用途1的特定一格式:可是一种专用的格式 =》pickle只有python可以识别
针对用途2的特定一格式:应该是一种通用、能够被所有语言识别的格式 =》json
import pickle
import ujson as json
import ujson
import json
3、如何序列化与反序列化
示范1
json_res = json.dumps([1, 'aaa', True, False])
l = json.loads(json_res)
print(l, type(l))
示范2:
序列化的结果写入文件的复杂方法
json_res = json.dumps([1, 'aaa', True, False])
with open('test.json', mode='wt', encoding='utf-8') as f:
f.write(json_res)
将序列化的结果写入文件的简单方法
with open('test.json', mode='wt', encoding='utf-8') as f:
json.dump([1, 'aaa', True, False], f)
从文件读取json格式的字符串进行反序列化操作的复杂方法
with open('test.json', mode='rt', encoding='utf-8') as f:
json_res = f.read()
l = json.loads(json_res)
print(l, type(l))
从文件读取json格式的字符串进行反序列化操作的简单方法
with open('test.json', mode='rt', encoding='utf-8') as f:
l = json.load(f)
print(l, type(l))
json验证: json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型
json.dumps({1, 2, 3, 4, 5})
json强调:一定要搞清楚json格式,不要与python混淆
l = json.loads('[1, "aaa", true, false]')
l = json.loads("[1,1.3,true,'aaa', true, false]")
print(l[0])
了解
l = json.loads(b'[1, "aaa", true, false]')
print(l, type(l))
with open('test.json', mode='rb') as f:
l = json.load(f)
res = json.dumps({'name': '哈哈哈'})
print(res, type(res))
res = json.loads('{"name": "u54c8u54c8u54c8"}')
print(res, type(res))
4、猴子补丁
在入口处打猴子补丁
def monkey_patch_json():
json.__name__ = 'ujson'
json.dumps = ujson.dumps
json.loads = ujson.loads
monkey_patch_json()
后续代码中的应用
json.dumps()
json.dumps()
json.dumps()
json.dumps()
json.dumps()
json.dumps()
json.dumps()
json.dumps()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
json.loads()
5.pickle模块
res = pickle.dumps({1, 2, 3, 4, 5})
print(res, type(res))
s = pickle.loads(res)
print(s, type(s))
configparser模块
一、ConfigParser简介
ConfigParser 是用来读取配置文件的包。配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。
[db]
db_host = 127.0.0.1
db_port = 69
db_user = root
db_pass = root
host_port = 69
[concurrent]
thread = 10
processor = 20
括号“[ ]”内包含的为section。紧接着section 为类似于key-value 的options 的配置内容。
二、ConfigParser 初始化对象
使用ConfigParser 首选需要初始化实例,并读取配置文件:
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
三、ConfigParser 常用方法
1、获取所用的section节点
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
print(config.sections())
2、获取指定section 的options。即将配置文件某个section 内key 读取到列表中:
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
r = config.options("db")
print(r)
3、获取指点section下指点option的值
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
r = config.get("db", "db_host")
print(r)
4、获取指点section的所用配置信息
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
r = config.items("db")
print(r)
5、修改某个option的值,如果不存在则会出创建
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
config.set("db", "db_port", "69")
config.write(open("ini", "w"))
运行结果
6、检查section或option是否存在,bool值
import configparser
config = configparser.ConfigParser()
config.has_section("section")
config.has_option("section", "option")
7、添加section 和 option
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
if not config.has_section("default"):
config.add_section("default")
if not config.has_option("default", "db_host"):
config.set("default", "db_host", "1.1.1.1")
config.write(open("ini", "w"))
运行结果
8、删除section 和 option
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
config.remove_section("default")
config.write(open("ini", "w"))
运行结果
9、写入文件
以下的几行代码只是将文件内容读取到内存中,进过一系列操作之后必须写回文件,才能生效。
import configparser
config = configparser.ConfigParser()
config.read("ini", encoding="utf-8")
写回文件的方式如下:(使用configparser的write方法)
config.write(open("ini", "w"))
hashlib模块
1、什么是哈希hash
hash一类算法,该算法接受传入的内容,经过运算得到一串hash值
hash值的特点:
I 只要传入的内容一样,得到的hash值必然一样
II 不能由hash值返解成内容
III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定
2、hash的用途
用途1:特点II用于密码密文传输与验证
用途2:特点I、III用于文件完整性校验
3、如何用
m = hashlib.md5()
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
res = m.hexdigest()
print(res)
m1 = hashlib.md5('he'.encode('utf-8'))
m1.update('llo'.encode('utf-8'))
m1.update('w'.encode('utf-8'))
m1.update('orld'.encode('utf-8'))
res = m1.hexdigest()
print(res)
模拟撞库
cryptograph = 'aee949757a2e698417463d47acac93df'
passwds = [
'alex3714',
'alex1313',
'alex94139413',
'alex123456',
'123456alex',
'a123lex',
]
dic = {}
for p in passwds:
res = hashlib.md5(p.encode('utf-8'))
dic[p] = res.hexdigest()
for k, v in dic.items():
if v == cryptograph:
print('撞库成功,明文密码是:%s' % k)
break
提升撞库的成本 = >密码加盐
m = hashlib.md5()
m.update('天王'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
m.update('盖地虎'.encode('utf-8'))
print(m.hexdigest())
m.update(文件所有的内容)
m.hexdigest()
f = open('a.txt', mode='rb')
f.seek()
f.read(2000)
m1.update(文见的一行)
m1.hexdigest()
suprocess模块
subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。
使用 subprocess 模块
subprocess 模块首先推荐使用的是它的 run 方法,更高级的用法可以直接使用 Popen 接口。
run 方法语法格式如下:
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
args:表示要执行的命令。必须是一个字符串,字符串参数列表。
stdin、stdout 和 stderr:子进程的标准输入、输出和错误。其值可以是 subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者 None。subprocess.PIPE 表示为子进程创建新的管道。subprocess.DEVNULL 表示使用 os.devnull。默认使用的是 None,表示什么都不做。另外,stderr 可以合并到 stdout 里一起输出。
timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
run 方法调用方式返回 CompletedProcess 实例,和直接 Popen 差不多,实现是一样的,实际也是调用 Popen,与 Popen 构造函数大致相同,例如:
实例
#执行ls -l /dev/null 命令
>>> subprocess.run(["ls", "-l", "/dev/null"])
crw-rw-rw- 1 root wheel 3, 2 5 4 13:34 /dev/null
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0)
returncode: 执行完子进程状态,通常返回状态为0则表明它已经运行完毕,若值为负值 "-N",表明子进程被终。
简单实例:
实例
import subprocess
def runcmd(command):
ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
if ret.returncode == 0:
print("success:",ret)
else:
print("error:",ret)
runcmd(["dir","/b"])#序列参数
runcmd("exit 1")#字符串参数
输出结果如下:
success: CompletedProcess(args=['dir', '/b'], returncode=0, stdout='test.py
', stderr='')
error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')
Popen() 方法
Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。
构造函数:
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(),
*, encoding=None, errors=None)
常用参数:
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:缓冲区大小。当创建标准流的管道对象时使用,默认-1。
0:不使用缓冲区
1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
正数:表示缓冲区大小
负数:表示使用系统默认的缓冲区大小。
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
cwd:用于设置子进程的当前目录。
env:用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承。
创建一个子进程,然后执行一个简单的命令:
实例
>>> import subprocess
>>> p = subprocess.Popen('ls -l', shell=True)
>>> total 164
-rw-r--r-- 1 root root 133 Jul 4 16:25 admin-openrc.sh
-rw-r--r-- 1 root root 268 Jul 10 15:55 admin-openrc-v3.sh
...
>>> p.returncode
>>> p.wait()
0
>>> p.returncode
这里也可以使用 p = subprocess.Popen(['ls', '-cl']) 来创建子进程。
Popen 对象方法
poll(): 检查进程是否终止,如果终止返回 returncode,否则返回 None。
wait(timeout): 等待子进程终止。
communicate(input,timeout): 和子进程交互,发送和读取数据。
send_signal(singnal): 发送信号到子进程 。
terminate(): 停止子进程,也就是发送SIGTERM信号到子进程。
kill(): 杀死子进程。发送 SIGKILL 信号到子进程。
实例
import time
import subprocess
def cmd(command):
subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
subp.wait(2)
if subp.poll() == 0:
print(subp.communicate()[1])
else:
print("失败")
cmd("java -version")
cmd("exit 1")
输出结果如下:
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
失败
作业
1、把登录与注册的密码都换成密文形式
2、文件完整性校验(考虑大文件)
3、注册功能改用json实现
4、项目的配置文件采用configparser进行解析