1、hashlib模块
hash是一种算法,该算法接收传入的内容,经过运算得到一串hash值(被hash计算后的该内容都是以二进制形式记录)
(如果把hash算法比喻为一座工厂,那传给hash算法的内容就是原料,生成的hash值就是生产出的产品)
#造出工厂
m=hashlib.md5()
#传入原材料
m.update("人生".encode("utf-8"))
#产出hash值
print(m.hexdigest())
用hash算法的原因在于hash值有三大特性:
1、只要传入的内容一样,得到的hash值必然一样#传入hash算出的内容为二进制
2、只要我们使用的hash算法固定,无论传入的内容有多大,得到的hash值的长度是固定的#比方说用hash内md5的算法不论内容多少长度都是32位
3、不可以用hash值逆推出原来的内容
基于1和2可以在下载文件时做文件一只性效验#源文件在hash计算后的值在传输到另一边之后,也会产生一个hash值,
与源文件处的hash值对比,如果hash值一致,那么下载的内容是没有任何丢失的。
基于1和3可以对密码进行加密#在传输内容进行中,内容有可能被截获,但是内容是经过hash计算过的非直观内容,需要破解后才能获取,同时在
密码内可以加入只有自己服务器端知道的“暗号”,比如在密码中加入其它字符串后在进行hash计算后,能大大增加安全性
password = input(">>:").strip()
m=hashlib.md5()
#可以额外添加update,增加密码内容私密性
m.update("你猜人生如何".encode("utf-8"))
m.update(password.encode("utf-8"))
print(m.hexdigest())
在使用hash函数前,必须要调用这个内置函数:import hashlib
需要转为hash的内容必须要转为二进制内容。
还有另外一种模块hmac
这个hmac模块是必须加入key然后和内容进行进一步的处理然后加密
如果在hmac.new内不填写任何东西,将会报错
import hmac
#hmac必须加入key
m=hmac.new("奋".encode("utf-8"))
#传入原材料
m.update("123".encode("utf-8"))
print(m)
print(m.hexdigest())
2、shutil
#将文件内容拷贝到领一个文件中
# import shutil
# with open("old.xml","r") as f,open("new.xml","w") as f2:
# shutil.copyfileobj(f,f2)
#将文件进行拷贝,目标文件无需存在
# with open("yf.txt","w") as f2:
# shutil.copyfileobj("yf.txt",f2)
#目标文件必须存在,仅拷贝权限。内容、组、用户均不变
# shutil.copystat('f1.log', 'f2.log')
# 拷贝文件和权限
# shutil.copy2('yf.log', 'f2.log')
# 拷贝文件和状态信息
# shutil.copy2('yf.txt', 'f2.log')
#制作压缩包,压缩之后的结果文件名,压缩算法与后缀
# import shutil
# shutil.make_archive("jie","gztar",root_dir=r"E:PycharmProjectskingday6.14")
#拷贝文件夹,先指定原文件夹,再指定目标文件夹,后面写多个值,所有pyc,结尾的,tmp开头的文件夹不会被拷贝
# import shutil
# shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
# import zipfile
# # 压缩
# z = zipfile.ZipFile("压缩后的文件名","w")
# z.write("需要压缩的文件")
# z.write("data.data")
# z.close()
#
# # 解压
# z = zipfile.ZipFile("解压的文件","r")
# z.extractall(path=".")
# z.close()
shelve模块
#序列化
import shelve
# d=shelve.open("db.txt",)
# d["egon"]={"pwd":"123","age":18,"sex":"male"}
# d["alex"]={"pwd":"123","age":73,"sex":"male"}#存的时候要这样
# #取出
# print(d["egon"]["pwd"])
# d.close()
# =======================================================
# dic1={"pwd":"123","age":18,"sex":"male"}
# dic2={"pwd":"123","age":73,"sex":"male"}#序列化字典
d=shelve.open('db.txt')
#想要修改文件内内容,必须后面writeback=True
# d['egon']=dic1#定义一个K方便拿出字典
# d['alex']=dic2
# 反序列化
# d=shelve.open("db.txt",writeback=True)
# d["egon"]["age"]=19#在有writeback=True的情况下能更改文件内容
print(d["egon"]["pwd"])
d.close()
#跨平台交互老版
import xml.etree.ElementTree as ET
tree = ET.parse("a.xml")
root=tree.getroot()
#对于任何标签都有三个特征:标签名、标签属性、标签的文本内容
# print(root.tag)#访问标签名<在这个内的第一个是标签名>
# print(root.attrib)#访问标签属性<在这里面的标签名后面跟的内容是属性 例如x="1">
# print(root.text)#访问文本内容,在标签名内部子标签上方跟的内容是文本内容
#print(list(root.iter("year")))#全文搜索,找到所有
# for year in root.iter("year"):#整个文档内只要有year存在就会全部查找出,root下面的子文件虽然没有,但是
# # iter能让器成为全文找,找到的是迭代器对象
# print(year.tag)
# print(year.attrib)
# print(year.text)
# print("="*100)
#print(root.find("country").attrib) #root的子节点找,只找一个
# print([country.attrib for country in root.findall("country")])#找到三个信息的文件列表
#1、查
#遍历整个文档
# for country in root:
# # print("======>国家%s" %country.attrib)#查看country下面的属性
# for item in country:
# print(item.tag)
# print(item.attrib)
# print(item.text)
#2、改
# for year in root.iter("year"):
# print(year.tag)
# year.attrib={"updated":"yes"}
# year.text=str(int(year.text)+1)
#
# tree.write("a.xml")
#
# #3、增
# for country in root:
# rank=country.find("rank")
# if int(rank.text) > 50:
# #print("符合条件的国家",country.attrib)
# tag=ET.Element("egon")
# tag.attrib={"updated":"yes"}
# tag.text="NB"
# country.append(tag)
# tree.write("a.xml")
#
# for country in root:
# tag = country.find("egon")
# #print(tag.bool(tag))
# if tag is not None:
# country.remove(tag)
# tree.write("a.xml")
configparser模块
import configparser
config = configparser.ConfigParser()#文件内必须是字典形式,configparser调configparser,拿到对象config
config.read("config.ini")#读取文件,结尾为cfg,ini,cnf结尾的文件,都是标题与配置模式
# print(config.sections())#sections获得文件内的所有标题
# print(config.options("section1"))#搜查对应标题内的配置项key全部显示出来
# print(config.items("section1"))#显示文件内所有的k与value,其中每个K与V都是元组,而全部元组都放到列表内
# res = config.get("section1","k2")#取出的为字符串形式,第一个为选择哪个标题,第二个为该标题内的k
# res =config.getint("section1","age")#年龄对应的k取出的为整型形式
# print(res,type(res))
# res=config.getfloat("section1","salary")#salary薪资对应的K取出的浮点型形式
# print(res,type(res))
#
# res=config.getboolean("section1","is_admin")#bool布尔值
# print(res,type(res))
面向过程编程
核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么然后干什么。。。
基于该思想编写程序好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的问题流程化、进而简单化
缺点:扩展性差
面向对象编程
核心对象二字,对象是特征与技能的结合体
基于该思想编写程序就好比是在创造一个世界,你就是这个世界的上帝,是一种上帝式的思维方式
优点:可扩展性强
缺点:编程的复杂度要高于面向过程
类
'''
类:种类、分类、类别
对象是特征与技能的结合体,类是一系列对象相似的特征与技能的结合体
强调:站的角度不同,总结出的类是截然不同的
在现实世界中:先有的一个个具体存在的对象,然后随着人类文明的发展才了分类的概念
在程序中:必须先定义类,后调用类来产生对象
站在老男孩选课系统的角度,先总结现实世界中的老男孩的学生对象
对象1:
特征:
学校='oldboy'
姓名='耗哥'
年龄=18
性别='male'
技能:
选课
对象2:
特征:
学校='oldboy'
姓名='猪哥'
年龄=17
性别='male'
技能:
选课
对象3:
特征:
学校='oldboy'
姓名='帅翔'
年龄=19
性别='female'
技能:
选课
站在老男孩选课系统的角度,先总结现实世界中的老男孩学生类
老男孩学生类:
相似的特征:
学校='oldboy'
相似的技能
选课
'''
#在程序中
#1、先定义类
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
#类体代码会在类定义阶段就立刻执行,会产生一个类的名称空间
# 类的本身其实就是一个容器/名称空间,是用来存放名字的,这是类的用途之一
# print(OldboyStudent.__dict__)
# print(OldboyStudent.__dict__['school'])
# print(OldboyStudent.__dict__['choose_course'])
# OldboyStudent.__dict__['choose_course']()
# print(OldboyStudent.school) #OldboyStudent.__dict__['school']
# print(OldboyStudent.choose_course) #OldboyStudent.__dict__['choose_course']
# OldboyStudent.choose_course(111)
# OldboyStudent.country='China' #OldboyStudent.__dict__['country']='China'
# OldboyStudent.country='CHINA' #OldboyStudent.__dict__['country']='China'
# del OldboyStudent.school
# print(OldboyStudent.__dict__)
#2、后调用类产生对象,调用类的过程,又称为类的实例化,实例化的结果称为类的对象/实例
stu1=OldboyStudent() # 调用类会得到一个返回值,该返回值就是类的一个具体存在的对象/实例
stu2=OldboyStudent() # 调用类会得到一个返回值,该返回值就是类的一个具体存在的对象/实例
stu3=OldboyStudent() # 调用类会得到一个返回值,该返回值就是类的一个具体存在的对象/实例