Python_模块

模块 module
01. 什么是模块:
模块是一个包含有一系列变量,函数,类等组成的程序组
模块是一个文件,模块文件通常以.py结尾
作用:
01. 让一些相关的变量,函数,类等有逻辑的组织在一起,使逻辑结构更加清晰
02. 模块中的变量,函数和类可提供给其它模块使用

02. 模块的分类:
内置模块(biultins), 在解释器的内部可以直接使用
标准库模块,安装python时已安装且可直接使用
第三方模块(通常为开源), 需要自己安装
用户自己编写的模块(可以作为其它人的第三方模块)

03. 模块的导入 import
import 语句
语法:
import 模块名1 [as 模块新名1][,模块名2 [as 模块新名2], ....]
示例:
import math # 导入数学模块
import sys, os # 导入 sys,os模块
作用:
  将某模块整体导入到当前模块中
用法:
模块名.属性名
help(模块名) 查看模块内的变量,函数,类等

模块的导入顺序:
01. 先导入内置模块
02. 再导入第三方模块
03. 最后导入自定义模块

04. from import 语句:
语法:
from 模块名 import 模块属性名1 [as 属性新名1], 模块属性名2 [as 属性新名2], ...
作用:
将某模块内的一个或多个属性导入到当前模块的作用域
示例:
from math import pi, sqrt
from math import factorial as fac
from math import sin
area = pi * 10 ** 2 # 可以直接使用导入的函数名或变量名

05. from import *语句:
语法:
from 模块名 import *
作用:
将某模块的所有属性导入到当前模块
示例:
from math import *
print(sin(pi/2))
print(factorial(10))

06. 导入模块时的路径索引顺序:
01. 索引程序的运行时路径(当前路径)
02. 搜索 sys.path里提供的路径
03. 搜索内置模块

07. 模块化编程的优点:
01. 有利于多人合作开发
02. 使代码更加易于维护
03. 提高代码的复用率
04. 模块化编程有助于解决函数名和变量名冲突(重名)问题,模块内的变量的作用域为模块内全局

08. 模块的加载过程:
01. 在模块导入时,模块的所有语句都会执行
02. 如果一个模块已经导入,则再次导入时不会重新执行模块内的语句

09. 模块的重新加载:
import imp
imp.reload(mymod) # 重新加载已经加载过的mymod模块

10. 模块被导入和执行的过程:
01. 先搜索相关路径找模块(.py)
02. 判断是否有此模块对应的.pyc文件,如果没有此文件,则用.py文件 生成相应的.pyc文件再进行加载
03. 如果文件已经存在,则判断.pyc文件和.py文件的修改时间,再决定是否重新生成.pyc文件

11. 模块的编译 compile:
编译 解释执行
mymod.py --->> mymod.pyc ---> python3

12. 模块的文档字符串:
模块内第一行没有赋值给任何变量的字符串为文档字符
此文档字符串可以用help函数查看
说明:
模块的文档字符串被绑定在模块的 __doc__属性上

13. __file__属性:
用来绑定模块对应的文件路径名
示例:
import mymod2
print(mymod2.__file__)

14. 模块的 __name__ 属性:
用来记录模块自身的名字
作用:
01. 记录模块名
02. 用来判断是否为主模块
__name__ 说明:
01. 当此模块作为主模块(也就是第一个运行的模块)运行时,__name__绑定'__main__'
02. 当此模块不是主模块时,模块为文件名去掉'.py'

15. 模块的 __all__列表:
模块中的__all__列表是一个用来存放可导出属性的字符串列表
作用:
当用from import * 语句导入模块时,只导入 __all__ 列表内的属性

16. 模块的隐藏属性:
模块中以'_' 开头的属性,在from import * 语句导入时,将不会导入,通常称这些属性为隐藏属性

17. 包(模块包) package:
包是将模块以文件夹的组织形式进行分组管理的方法
作用:
1. 将一系列模块进行分类管理,有利于防止命名冲突
2. 可以在需要时加载一个或部分模块而不是全部模块
包示例:
mypack/
__init__.py
menu.py
games/
__init__.py
contra.py # 魂斗罗
supermario.py # 超级玛丽
tanks.py # 坦克大战
office/
__init__.py
excel.py
word.py
powerpoint.py
包的导入语法:
如果是直接导入一个包,那么相当于执行了这个包中的__init__文件
并不会帮你把这个包下面的其他包以及py文件自动的导入到内存
如果你希望直接导入包之后,所有的这个包下面的其他包以及py文件都能直接通过包来引用
那么你要自己处理__init__文件
import 包名 [as 包别名]
import 包名.模块名 [as 模块新名]
import 包名.子包名.模块名 [as 模块新名]
from 包名 import 模块名 as 模块新名
from 包名.子包名 import 模块名 [as 模块新名]
from 包名.子包名.模块名 import 属性名[as 属性新名]
from 包名 import *
from 包名.模块名 import *

18. __init__.py 文件:
是常规包内必须存在的文件,__init__.py会在导入包时被自动调用
作用:
01. 编写此包的内容
02. 在内部添加包的文档字符串
03. 在__init__.py 文件内可以加载此包所依懒的其它模块

19. 包的__all__列表:
作用:
用来记录此包中有哪儿些子包或模块需要导入
当用from 包 import * 语句导入时,只查 找__all__中的模块或子包
说明:
__all__列表只在from xxx import *语句时起作用
说明:
当子包或子包内的模块被导入时,上一层的包也会被先导入
例如:
import mypack.games.contra
实质会先导入mypack,再导入games,再导入contra

20. 包的相对导入:
包的相对导入是指包内的模块的相互导入
语法:
from 相对路径包或模块 import 属性或模块名

from 相对路径包或模块 import *
相对路径:
在 from xxxx import 语句中,xxxx 部分可以使用相对路径
. 代表当前目录
.. 代表上一级目录
... 代表上二级目录
.... 以此类推
注:
1. 相对导入时不能超出包的外部
2. 相的导入要避免循环导入

21. 标准输入输出文件:
sys.stdin # 标准输入
sys.stdout # 标准输出
sys.stderr # 标准错误输出
模块名: sys
说明:
每一个python程序启动后都会有以上三个文件已经打开供我们使用
Linux下 Ctrl + D输入文件结束符

示例1:
# 此示例示意sys.stdin的用法
import sys
print("请输开始输入:")

# s = sys.stdin.read(10) # 默认从键盘获取数据
# print(s)
# s2 = sys.stdin.read(10)
# print(s2)

s = sys.stdin.read()
print("您刚才输入的是:", s)

示例2:
# 此程序示意标准输出sys.stdout 和标准错误输出 sys.stderr
import sys # 导入sys模块

sys.stdout.write("hello world\n")
# 等同于 print('hello world', end='\n')

# 以下程序会出错
# sys.stdout.close()
# print("程序结束!")
sys.stderr.write("我的出现是个错误!\n")


Python常用模块:

01. time 时间模块:
import time

# time()取时间戳-->做计算
print(time.time()) # 1553274079.3324106秒-->1970年凌晨到现在的时间秒

# localtime结构化时间-->当地时间
t = time.localtime() # 默认参数time.time()
print(t)
print(t.tm_year) # 打印年

# gmtime结构化时间-->UTC世界标准时间, 比中国时间慢8小时
print(time.gmtime()) # 格林时间

# mktime结构化时间转换成时间戳
print(time.mktime(t))

# strftime结构化时间转换成字符串时间
print(time.strftime("%Y-%m-%d %X", t)) # Y年 m月 d日 X时分秒 t结构化时间

# strptime将字符串时间转换成结构化时间
print(time.strptime("2019:03:23:01:26:11", "%Y:%m:%d:%X"))

# asctime()将结构化时间转换成固定的字符串表达方式-->默认参数取当前结构化时间
print(time.asctime()) # 周月日时分秒年

# ctime()将时间戳时间转换成固定的字符串表达方式-->默认参数取当前时间戳
print(time.ctime()) # 周月日时分秒年

# sleep()线程推迟指定时间运行,单位秒
time.sleep(1) # 睡一秒


# 日常时间显示
import datetime
print(datetime.datetime.now()) # 2019-03-23 01:54:52.165174

02. random 随机模块:
# random随机模块
import random
ret = random.random() # (0,1)随机取浮点数
ret = random.randint(1, 3) # [1, 3]随机取整数
ret = random.randrange(1, 3) # [1, 3)随机取整数
ret = random.choice([11, 22, 33]) # [可迭代序列]取随机值
ret = random.sample([11, 22, 33], 2) # [可迭代序列]取随机2个值
ret = random.uniform(1,3) # (1, 3)取指定范围的浮点数
print(ret)
item = [1, 2, 3, 4, 5]
random.shuffle(item) # 随机打乱列表的序列
print(item)

03. os 模块:
# os模块是与操作系统交互的一个模块
import os

# getcwd获取当前工作目录,即当前python脚本工作目录路径
print(os.getcwd()) # G:\PycharmProjects\11_模块\lnh_massage

# chdir改变当前脚本的工作目录,相当于shell下的cd命令
os.chdir("test1")
print(os.getcwd()) # G:\PycharmProjects\11_模块\lnh_massage\test1
os.chdir("..")
print(os.getcwd()) # G:\PycharmProjects\11_模块\lnh_massage

# curdir返回当前目录
print(os.curdir) # .

# pardir获取当前父目录字符串名
print(os.pardir) # ..

# makedirs 可递归创建文件夹
os.makedirs("makir1/mkdir2")

# removedirs 文件夹为空则可递归删除文件夹,知道非空为止
os.removedirs("makir1/mkdir2")

# mkdir 生成前单级目录
os.mkdir("test2")

# rmdir 删除单级空目录,目录不为空则无法删除
os.rmdir("test2")

# listdir 列出指定文件下的所有文件和子目录,包含影藏文件,返回一个列表
print(os.listdir("test1"))

# remove 删除一个文件
os.remove("test1/111")

# rename 重命名文件/目录
os.rename("test1", "test1")

# stat 获取文件/目录信息
print(os.stat(r"G:\PycharmProjects\11_模块\lnh_massage"))

# sep 查看操作系统的特定路径分割符
print(os.sep) # Windows为:“\”,Linux为:“/”

# linesep 查看当前平台使用的终止符
print("终止符", os.linesep) # win下“\r\n”,linux下“\n”

# pathsep 查看用于分割文件路径的字符串
print("分隔文件", os.pathsep) # win下“;”,linux下“:”

# name 以字符串指示查看当前使用平台
print("使用平台", os.name) # win下“nt”,linux下“posix”

# system 运行shell命令,直接显示
os.system("ping 127.0.0.1")

# environ 获取系统环境变量
print(os.environ)

# path.abspath() 返回规范化的path绝对路径
print(os.path.abspath(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # G:\PycharmProjects\11_模块\lnh_massage\test1

# path.split 将path分割成目录和文件名,返回元组
print(os.path.split(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # ('G:\\PycharmProjects\\11_模块\\lnh_massage', 'test1')

# path.dirname 返回path.abspath()的第一个元素,目录
print(os.path.dirname(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # G:\PycharmProjects\11_模块\lnh_massage

# basename 返回path.abspath()的第二个元素,文件名
print(os.path.basename(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # test1

# path.exists 判断path是否存在,返回布尔值
print(os.path.exists(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # True

# path.isabs 判断path是否是绝对路径,返回布尔值
print(os.path.isabs(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # True

# path.isfile 判断path是否是一个存在的文件,返回布尔值
print(os.path.isfile(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # False

# path.isdir 判断path是否是一个存在的目录
print(os.path.isdir(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # True

# path.join 路径拼接,会自动去找当前操作系统的路径分割符拼接
a = r"G:\PycharmProjects"
b = r"11_模块\lnh_massage\test1"
print(os.path.join(a, b)) # G:\PycharmProjects\11_模块\lnh_massage\test1

# path.getatime 返回path所指向的文件或目录最后一次存取时间
print(os.path.getatime(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # 1553962262.1905563

# path.getmtime 返回path所指向的文件或目录最后一次修改时间
print(os.path.getmtime(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # 1553962262.1905563

# path.getsize 返回path所指向的文件的大小, 单位为字节
print(os.path.getsize(r"G:\PycharmProjects\11_模块\lnh_massage\test1")) # 397

模块导入添加path路径示例:
import sys
import os
# lst = __file__.split('/')
# # base_path = '/'.join(lst[:-2])
base_path = os.path.dirname(os.path.dirname(__file__))
sys.path.append(base_path)
from core import main

04. sys 模块:
# sys模块与python解释器交互的一个模块
import sys, time

# eixt(0) 退出程序
print(sys.exit(0))

# argv 命令行参数,返回列表,第一个元素是程序本身路径
print(sys.argv) # ['D:\\ProgramData\\Anaconda3\\Scripts\\ipython']

# version 获取python解释器版本信息
print(sys.version) # 3.7.1 (default, Dec 10 2018, 22:54:23) [MSC v.1915 64 bit (AMD64)]

# path 返回模块的搜索路径
print(sys.path)

# platform 返回操作系统平台名称
print(sys.platform) # win32

# 进度条
for i in range(100):
sys.stdout.write("#") # 向屏幕显示相应的内容
time.sleep(0.1)
sys.stdout.flush() # 刷新缓存

05. json&pickle 模块:
import json # 序列化模块,将数据转换成json的字符串

dic = {"name": "coco"}
data = json.dumps(dic) # 转换成所有语言都支持的json的字符串
print(data)
print(type(data))
f = open("test2", "w")
# data = json.dump(dic, f) # 直接转化写入文件
f.write(data)
f.close()

f_read = open("test2", "r")
data1 = json.loads(f_read.read()) # 将json处理的字符串还原原来的数据类型
# data1 = json.load(f) # 直接读取还原
print(data1)
print(type(data1))
f_read.close()

# pickle 序列化模块,将数据转换成字节,还支持函数和类的转换
import pickle


dic1 = {"name": "coco"}
data2 = pickle.dumps(dic1) # 转换成所有语言都支持的pickle的bytes
print(data2)
print(type(data2))
f1 = open("test3", "wb")
# data = pickle.dump(dic1, f) # 直接转化写入文件
f1.write(data2)
f1.close()

f1_read = open("test3", "rb")
data3 = pickle.loads(f1_read.read()) # 将pickle处理的bytes还原原来的数据类型
# data3 = pickle.load(f) # 直接读取还原
print(data3)
print(type(data3))
f_read.close()

06. shelve 模块:
常用方式:
文件改动的比较少, 读文件的操作比较多
且大部分读取都需要基于某个key获得某个value
import shelve

f = shelve.open(r"shelve.txt") # 生成一个空文本
f["stu1_info"] = {"name": "coco", "age": "26"} # 将字典放入文本
f["stu2_info"] = {"name": "angels", "age": "18"}

f.close()
print(f.get("stu1_info")["age"]) # 26

07. xml 模块:
import xml.etree.ElementTree as ET # as 取别名

tree = ET.parse("xml_lesson") # parse解析xml,返回一个解析对象
root = tree.getroot() # getroot 取根节点
print(root.tag) # tag 拿到根节点的标签名

# 遍历xml文档
for child in root:
print(child.tag, child.attrib) # tag标签名,attrib标签属性
for i in child:
print(i.tag, i.text) # text标签的内容

# 只遍历year节点
for node in root.iter("year"): # iter指定拿root根下的某个节点
print(node.tag, node.text)

# 修改
for node in root.iter("year"):
new_year = int(node.text) + 1 # 修改year标签内容
node.text = str(new_year) # 重新赋值修改内容
node.set("updated", "yes") # 为year标签添加属性
tree.write("xml_lesson") # 把修改后内容从新写一个文件,同名则覆盖原文件

# 删除
for country in root.findall("country"): # findall 找root的所有country标签
rank = int(country.find("rank").text) # find 找country下的rank标签
if rank >= 50:
root.remove(country)
tree.write("xml_output") # 把修改后内容从新写一个文件,同名则覆盖原文件


# 创建一个xml
new_xml = ET.Element("namelist") # Element 创建根节点
name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
age = ET.SubElement(name, "age", attrib={"checked": "no"})
sex = ET.SubElement(name, "sex")
sex.text = "26"

et = ET.ElementTree(new_xml) # 生成文档对象
et.write("xml_text.xml", encoding="utf-8", xml_declaration=True) # 写出到文档
ET.dump(new_xml) # 打印生成格式

08. re 正则模块:
import re

# 普通字符 findall("匹配规则", "匹配内容")
# findall会优先显示分组中的内容,要想取消分组优先,(?:正则表达式)
print(re.findall("coco", "my name is coco hao are you"))

# 元字符:. ^ $ * + ? {} [] | () \
# .通配符,除了\n以外的所有字符都可以用.代替,一个点代指1个字符
print(re.findall("m.....e", "my name is coco hao are you"))

# ^只能在字符串开头匹配内容
print(re.findall("^m..n", "my name is coco hao are you"))

# $只能在字符串结尾匹配内容
print(re.findall("e...u$", "my name is coco hao are you"))

# *匹配0-无穷次的内容
print(re.findall("^d*", "dddddefghddd"))

# +匹配1-无穷次的内容
print(re.findall("d+", "dddddefghddd"))

# ?匹配0次或者1次的内容
print(re.findall("ghf?", "dddddefghddd"))

# {}匹配指定次数的内容
print(re.findall("ghd{0,2}", "dddddefghddd"))

# []字符集,字符集里的功能符号只有- ^ \
print(re.findall("x[yz]", "xyaaaxz"))
print(re.findall("x[a-z]", "xyappxcappxzapp")) # -范围
print(re.findall("x[^a-z]", "xyappxcappxzappx1")) # ^非
print(re.findall("\([^()]*\)", "1+(2*3+5-(2-(5-4)))")) # \转义

# \转义元字符
print(re.findall("5\*3\+2", "5*3+2-10"))
# \d:匹配任意十进制数,相当于[0-9]
print(re.findall("\d+", "1+(2*3+5-(2-(5-4)))"))
# \D:匹配任意非十进制数,相当于[^0-9]
print(re.findall("\D+", "1+(2*3+5-(2-(5-4)))"))
# \s:匹配任何空白字符,相当于[\t\r\f\v]
print(re.findall("\s+", "hello world"))
# \S:匹配任何非空白字符,相当于[^\t\r\f\v]
print(re.findall("\S+", "hello world"))
# \w:匹配任何字母数字,相当于[a-zA-z0-9_]
print(re.findall("\w+", "hello world 12345"))
# \W:匹配任何非字母数字,相当于[^a-zA-z0-9_]
print(re.findall("\W+", "hello world 12345"))
# \b:匹配一个特殊字符边界,如空格 & # 等
print(re.findall(r"lo\b", "hello hello#hello&")) # r 后面的内容pythonIDE不解释,交给re解释

# |管道符-->或
print(re.findall("ac|b", "123ac566546b"))

# ()分组
print(re.findall("(abc)+", "abc11abc22abc33"))
# search 如果search中有分组的话,通过group(n)就能够拿到group中的匹配的内容
# (?P<name>正则表达式) 表示给分组起名字
ret = re.search("(?P<name>[a-z]+)(?P<age>\d+)","coco26alex30").group("name")
print(ret) # coco

# mach查找方法
ret = re.match("a", "abc").group() # 通search,不同在以字符串开始出进行匹配
print(ret) # a

# split分割方法, 遇到分组 会保留分组内被切掉的内容
ret = re.split("[ab]", "abcd") # 先按a分割得""和"bcd"再对""和"bcd"按b分割
print(ret) # ['', '', 'cd']

# sub替换方法
ret = re.sub("\d+", "A", "d22d33sd44", 2)
print(ret) # dAdAsd44

# subn替换方法
ret = re.subn("\d+", "A", "d22d33sd44")
print(ret) # ('dAdAsdA', 3)

# compile编译方法
# 节省时间:只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率
com = re.compile("\d+")
ret = com.findall("avc11sss22ssgg33")
print(ret) # ['11', '22', '33']

# finditer方法处理后返回迭代器, 空间效率
ret = re.finditer("\d+", "asd22sa33")
print(ret) # <callable_iterator object at 0x0000000003548BE0>
print(next(ret).group()) # 22
print(next(ret).group()) # 33

# ?:去优先级
ret= re.findall("www\.(baidu|163)\.com", "aawww.baidu.combb")
print(ret) # ['baidu']
ret= re.findall("www\.(?:baidu|163)\.com", "aawww.baidu.combb")
print(ret) # ['www.baidu.com']

09. logging 日志模块:
import logging

# basicConfig定义日志
logging.basicConfig(
level=logging.DEBUG, # 设置显示日志级别
filename="logger.log", # 设置追加写出日志
filemode="w", # 覆盖写入
format="%(asctime)s %(filename)s [line:%(lineno)d] %(message)s" # 设置写出格式
)

# 日志的五个级别
logging.debug("debug message") # 调试模式
logging.info("info message") # 基础信息
logging.warning("warning massage") # 警告
logging.error("error massage") # 错误
logging.critical("critical massage") # 严重错误

# getLogger创建对象定义日志
def logget():
logget = logging.getLogger() # 创建一个logger对象
fh = logging.FileHandler("logger1.log") # 创建一个文件管理操作符,向文件发送日志
ch = logging.StreamHandler() # 创建一个屏幕管理操作符,向屏幕发送日志

fm = logging.Formatter("%(asctime)s %(message)s") # 创建一个日志输出的格式,定义日志格式
fh.setFormatter(fm) # 文件管理操作符 绑定一个 格式
ch.setFormatter(fm) # 屏幕管理操作符 绑定一个 格式

logget.addHandler(fh) # logger对象 绑定 文件管理操作符
logget.addHandler(ch) # logger对象 绑定 屏幕管理操作符
logget.setLevel("DEBUG") # 设置日志显示级别
return logget


logget = logget()
logget.debug("debug message")
logget.info("info message")
logget.warning("warning massage")
logget.error("error massage")
logget.critical("critical massage")

10. configparser 配置文件模块:
import configparser

config = configparser.ConfigParser()

config["DEFAULT"] = {
"Sever": "45",
"Compression": "yes",
"CompressionLevel": "9"
}

config["bt.org"] = {}
config["bt.org"]["User"] = "coco"

config["sever.com"] = {}
top = config["sever.com"]
top["Host Ip"] = "127.0.0.1"
top["Host Port"] = "8080"

with open("example.ini", "w") as configfile:
config.write(configfile)

# 查配置文件
config.read("example.ini")
print(config.sections()) # 读除默认块以外的块名['bt.org', 'sever.com']
print(config["bt.org"]["user"]) # coco
for key in config:
print(key)

print(config.options("bt.org")) # ['user', 'sever', 'compression', 'compressionlevel']
print(config.items("bt.org")) # [('sever', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('user', 'coco')]
print(config.get("bt.org", "user")) # coco

# 添加,修改,删除
config.add_section("yun") # 添加块
config.set("yun", "k1", "11") # 添加键值对,同名覆盖即修改
config.remove_option("sever.com", "host port") # 删除块下的某个键值对
config.remove_section("sever.com") # 删除块及块里面的的所有键值对

config.write(open("i.cfg"), "w")

11. hashlib 算法摘要模块:
import hashlib

# md5
# md5是一个算法,32位的字符串,每个字符都是一个十六进制
# md5算法 效率快 算法相对简单
obj = hashlib.md5("ssasdf".encode(encoding="utf8")) # 自定义加盐
obj.update("coco".encode(encoding="utf8")) # 原生md5加密
print(obj.hexdigest()) # 516dacada2fea0112265e3a474dee5fe

# sha256
obj = hashlib.sha256("ssasdf".encode(encoding="utf8")) # 自定义加盐
obj.update("coco".encode(encoding="utf8")) # 原生md5加密
print(obj.hexdigest()) # 577cce053410c4bf7ccee892b3d92c55f20c56b773276a326777a4535a021909

# sha1也是一个算法,40位的字符串,每个字符都是一个十六进制
# 算法相对复杂 计算速度也慢
md5_obj = hashlib.sha1()
md5_obj.update(s1.encode('utf-8'))
res = md5_obj.hexdigest()
print(res,len(res),type(res))

# 动态加盐
username = input('username : ')
passwd = input('password : ')
md5obj = hashlib.md5(username.encode('utf-8'))
md5obj.update(passwd.encode('utf-8'))
print(md5obj.hexdigest()) # ee838c58e5bb3c9e687065edd0ec454f

# 文件的一致性校验
md5_obj = hashlib.md5()
with open('5.序列化模块_shelve.py','rb') as f:
md5_obj.update(f.read())
ret1 = md5_obj.hexdigest()

md5_obj = hashlib.md5()
with open('5.序列化模块_shelve.py.bak','rb') as f:
md5_obj.update(f.read())
ret2 = md5_obj.hexdigest()
print(ret1,ret2)

# 大文件的已执行校验
md5_obj = hashlib.md5()
with open('5.序列化模块_shelve.py.bak','rb') as f:
md5_obj.update(f.read())
# 循环 循环的读取文件内容
# 循环的来update
print(md5_obj.hexdigest())

转载于:https://www.cnblogs.com/tangxuecheng/p/11216311.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值