1常用模块
1.1 xml
xml是实现不同语言或程序之间进行数据交换的协议
xml的格式如下:
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
对xml的基本操作
import xml.etree.cElementTree as ET
tree = ET.parse("aa.xml")
root = tree.getroot()
for child in root:
print("=========>",child)
for item in child:
print(item.tag, item.attrib, item.text)
1.1.1 查找元素
import xml.etree.cElementTree as ET
tree = ET.parse("aa.xml")
root = tree.getroot() # 1. iter:扫描整个xml文档树,找到所有
years = root.iter("year")
for year in years:
print(year) # 2. find:谁来调用,就从谁的下一层开始查找,只找一个
res1 = root.find("country")
print(res1) # 3. findall:谁来调用,就从谁的下一层开始查找,找到所有
res2 = root.findall("country")
print(res2)
1.1.2 更新
找到整个文档树下的year标签,并且把year的值加1,添加属性updated和version
import xml.etree.cElementTree as ET
tree = ET.parse("aa.xml")
root = tree.getroot() years = root.iter("year") # 扫描整个xml文档树,找到所有
for year in years:
year.text = str(int(year.text)+1)
year.set("updated","yes")
year.set("version","1.0")
tree.write("aa.xml")
1.1.3 删除
import xml.etree.cElementTree as ET
tree = ET.parse("aa.xml")
root = tree.getroot() countries = root.iter("country")
for country in countries:
rank = country.find("rank")
if int(rank.text) > 10:
country.remove(rank)
tree.write("aa.xml")
1.1.4 增加
import xml.etree.cElementTree as ET
tree = ET.parse("aa.xml")
for country in tree.iter("country"):
e = ET.Element("jack")
e.text = "jack"
e.attrib = {"age": ""}
country.append(e)
tree.write("aa.xml")
1.2 configparser
配置文件:
# a.ini
[egon]
name = egon
age = 18
is_admin = True
salary = 3.1 [jack]
name = jack
age = 25
is_admin = False
salary = 6.5
1.2.1 取值
import configparser config = configparser.ConfigParser()
config.read("a.ini") print(config.sections()) # 查看所有的标题
print(config.options(config.sections()[0])) # 查看某个标题下的配置项
res = config.get("jack", "name") # 查看某个标题下的某个配置项的值
print(res) res1 = config.getint("egon","age")
print(type(res1)) res2 = config.getfloat("egon", "salary")
print(type(res2)) res3 = config.getboolean("egon", "Is_Admin")
print(type(res3))
1.2.2 修改
import configparser config = configparser.ConfigParser()
config.read("a.ini") config.remove_section("jack")
config.remove_option("egon", "age")
config.add_section("alex")
config.set("alex", "name", "SB") config.write(open("a.ini","w"))
1.3 Hashlib
Hashlib:主要是校验文本内容
hash:是一种算法,python3中代替了md5模块和sha模块,主要提供SHA1、SHA224、SHA256、SHA384、SHA512
hash有三个特点:
1.内容相同则hash运算结果相同,内容稍微改变,则hash值则变化
2.hash结果不可逆推
3.相同算法:无论校验多大的数据,得到的哈希值长度固定
import hashlib m = hashlib.md5() # md5计算出来的结果,是组合一起的结果
m.update("hello".encode("utf-8"))
m.update("world".encode("utf-8"))
print(m.hexdigest()) # 运行结果:fc5e038d38a57032085441e7fe7010b0 m2 = hashlib.md5()
m2.update("helloworld".encode("utf-8"))
print(m2.hexdigest()) # 运行结果:fc5e038d38a57032085441e7fe7010b0 m = hashlib.md5()
with open("my.txt","rb") as f:
for line in f:
m.update(line)
print(m.hexdigest()) # 耗费内存,不推荐使用
m = hashlib.md5()
with open("my.txt","rb") as f:
m.update(f.read())
print(m.hexdigest())
加盐,防止通过暴力破解密码
import hashlib
password = "helloworld"
m = hashlib.md5("yihangbailushangqingtian".encode("utf-8"))
m.update(password.encode("utf-8")) passwd_md5 = m.hexdigest()
print(passwd_md5)
hmac模块,与md5类似,只是在初始化的时候,必须传一个key值;首先保证初始的key一样,随后多次update内容一样,加密结果一样
import hmac
h = hmac.new("hello".encode("utf-8"))
h.update("world".encode("utf-8"))
print(h.hexdigest()) # 运行结果:0e2564b7e100f034341ea477c23f283b h2 = hmac.new("hello".encode("utf-8"))
h2.update("wor".encode("utf-8"))
h2.update("ld".encode("utf-8"))
print(h2.hexdigest()) # 运行结果:0e2564b7e100f034341ea477c23f283b
1.4 suprocess
suprocess模块,用来执行命令的;在linux系统中,用来执行shell命令;
import subprocess
res = subprocess.Popen(r"dir D:\python\code\Learning\day07",shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# print(res.stdout.read())
print("正确====>",res.stdout.read().decode("gbk")) # 命令执行正确,输出结果 res2 = subprocess.Popen(r"error dir D:\python\code\Learning\day07",
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# print(res.stdout.read())
print("错误====>",res2.stderr.read().decode("gbk")) # 命令执行错误,输出结果
print("错误====>",res2.stderr.read().decode("gbk")) # 管道的内容已经输出,管道内已经无内容 #dir file_path | findstr xml$
res2 = subprocess.Popen(r"dir D:\python\code\Learning\day07\xml模块\aa.xml",
shell=True,
stdout=subprocess.PIPE)
res3 = subprocess.Popen("findstr xml$",shell=True,
stdin=res2.stdout,
stdout=subprocess.PIPE)
print(res3.stdout.read().decode("gbk"))
2 面向对象设计
2.1 介绍
面向过程:核心是过程二字,过程指的是问题的解决步骤,即先干什么再干什么,基于面向过程取设计程序就好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的问题流程化,进而简单化
缺点:可扩展性差
应用场景:脚本程序,比如linux系统管理脚本,著名案例:linux内核,httpd,git
面向对象:核心是对象二字,对象就是特征与技能的结合体,如果把设计程序比喻成创造一个世界,那你就是这个世界的上帝,与面向过程机械流水的模拟形成鲜明的对比,面向对象更加注重的对现实世界的模拟
优点:可扩展性强
缺点:极易出现过度设计,不能控制流程的进度
类即种类、类别,对象是特征和技能的结合体,那么类就是一系列对象相似的特征与技能的结合体
在现实世界中:先有一个个具体存在的对象---> 总结相似之处 ---> 现实中的类
在程序中:一定是先定义类,后调用类来产生对象
2.2 现实中的对象
第一阶段:现实中对象,总结出现实中类
obj1:
特征
学校=oldboy
名字=李大炮
年龄=18
性别=女
技能
学习
吃饭 obj2:
特征
学校=oldboy
名字=张全蛋
年龄=28
性别=男
技能
学习
吃饭 obj3:
特征
学校=oldboy
名字=牛榴弹
年龄=18
性别=女
技能
学习
吃饭
现实中的老男孩学生类:
相似的特征
学校=oldboy
相似的技能
学习
吃饭
2.3 程序中的类
第二阶段:程序中的类,产生程序中的对象
1.怎么定义类
2.类的名称空间
3.类的属性增删改查操作
class OldboyStudent:
school = 'oldboy' # 类的数据属性,静态属性
def learn(self): # 类的函数属性,动态属性
print('is learning') def eat(self):
print('is eating') # 类体的代码在类定义阶段就会执行,
# 必然会产生类的名称空间,用__dict__属性查看
print(OldboyStudent.__dict__)
print(OldboyStudent.__dict__['school'])
print(OldboyStudent.__dict__['learn']) # 类的属性访问,包括数据属性、函数属性
print(OldboyStudent.school)
print(OldboyStudent.learn) # 利用名称空间,调用类的函数
OldboyStudent.learn(12) # 执行结果:is learning # 操作属性
OldboyStudent.x=1111 # 新增属性
OldboyStudent.school='Oldboy' # 修改属性
del OldboyStudent.school # 删除属性
2.4 程序中的对象
产生程序中的对象:类名加括号,调用类,产生一个该类的实际存在的对象,该调用过程称为实例化,产生的结果又可以成为实例
class OldboyStudent:
school = 'oldboy'
#obj1,'李大炮',18,'女'
def __init__(self,name,age,sex): # 在实例化时,产生对象之后执行
if not isinstance(name,str):
raise TypeError('名字必须是字符串类型')
self.name=name
self.age=age
self.sex=sex
# return None #__init__方法必须返回None def learn(self):
print('is learning') def eat(self):
print('is eating') obj1 = OldboyStudent('李大炮',18,'女')
# 第一步:先产生一个空对象obj1
# 第二步:OldboyStudent.__init__(obj1,'李大炮',18,'女')
print(obj1.__dict__) #查看对象的名称空间 obj2=OldboyStudent('张全蛋',28,'男')
obj3=OldboyStudent('牛榴弹',18,'女') # python中禁止通过__dict__操作类,但可以通过字典操作对象
print(obj1.name) # obj1.__dict__['name']
obj1.name='大炮'
print(obj1.__dict__)
obj1.__dict__['name']='炮'
print(obj1.name) obj1.__dict__.pop('name')
print(obj1.__dict__)
2.5 __init__
__init__:在初始化对象时,进行初始化工作,在实例化时,产生对象之后执行
obj1 = OldboyStudent('李大炮',18,'女')
# 第一步:先产生一个空对象obj1
# 第二步:OldboyStudent.__init__(obj1,'李大炮',18,'女')
__init__:不仅仅为定制对象添加数据属性代码,可以添加任何可执行代码,其中包括用户数据检查代码;既然是函数,必须有返回值,但是该函数必须None
def __init__(self,name,age,sex): # 在实例化时,产生对象之后执行
if not isinstance(name,str):
raise TypeError('名字必须是字符串类型')
self.name=name
self.age=age
self.sex=sex
# return None #__init__方法必须返回None
2.6 类的数据属性
对象可以访问类的数据属性,结论:类的数据属性共享给所有对象使用,id都一样
class OldboyStudent:
school = 'oldboy' def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def learn(self):
print('%s is learning' %self.name) def eat(self):
print('is eating') # 对象可以访问类的数据属性,结论:类的数据属性共享给所有对象使用,id都一样
obj1 = OldboyStudent('李大炮', 18, '女')
obj2 = OldboyStudent('张全蛋', 28, '男')
obj3 = OldboyStudent('牛榴弹', 18, '女')
print(obj1.school,id(obj1.school)) # 运行结果:oldboy 32215480
print(obj2.school,id(obj2.school)) # 运行结果:oldboy 32215480
print(obj3.school,id(obj3.school)) # 运行结果:oldboy 32215480
print(OldboyStudent.school,id(OldboyStudent.school)) # 运行结果:oldboy 32215480
2.7 类的函数属性
类的函数属性是绑定给所有对象使用的,绑定给不同的对象就是不同的绑定方法,类可以访问自己的函数属性
绑定方法:绑定给谁,就由谁来调用,谁来调用就把“谁”本身当做第一个参数传入
class OldboyStudent:
school = 'oldboy' def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def learn(self):
print('%s is learning' %self.name) def eat(self):
print('is eating') obj1 = OldboyStudent('李大炮', 18, '女')
obj2 = OldboyStudent('张全蛋', 28, '男')
obj3 = OldboyStudent('牛榴弹', 18, '女')
# 类的函数属性是绑定给所有对象使用的,绑定给不同的对象是不同的绑定方法
# 类肯定可以访问自己的函数属性
OldboyStudent.learn(obj1)
OldboyStudent.learn(obj2)
OldboyStudent.learn(obj3) # 绑定方法:绑定给谁,就由谁来调用,谁来调用就把“谁”本身当做第一个参数传入
obj1.learn() # OldboyStudent.learn(obj1)
obj2.learn() # OldboyStudent.learn(obj1)
obj3.learn() # OldboyStudent.learn(obj1) # 在python3中类型就类,python3中一切皆为对象
l1=list()
l2=list() # l1.append(3) 等价于 list.append(l1,3)
list.append(l1,3)
print(l1)
print(l2)
2.8 属性查找顺序
属性查找顺序:先从对象的__dict__中找,然后到类的__dict__中找,然后再从父类中进行查找...
class OldboyStudent:
school = 'oldboy' def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def learn(self):
print('%s is learning' %self.name) def eat(self):
print('is eating') obj1 = OldboyStudent('李大炮', 18, '女')
# 属性查找顺序:先从对象的__dict__中找,然后到类的__dict__中找,然后再从父类中进行查找...
OldboyStudent.school = 'oldgirl'
obj1.school = 'self school'
print(obj1.__dict__)
print(obj1.school)
2.9 类实例化次数
统计类被实例化对象次数的计数功能,就是通过类的数据属性进行实现的
class Foo:
count = 0
def __init__(self,x,y,z):
self.x = x
self.y = y
self.z = z
Foo.count += 1 obj1=Foo(1,1,1)
obj2=Foo(1,2,1)
obj3=Foo(1,2,3) print(obj1.count)
print(Foo.count)
2.10 对象之间的交互
class Garen:
camp = 'Demacia'
def __init__(self,nickname, life_value = 100, aggresivity = 50):
self.nickname = nickname
self.life_value = life_value
self.aggresivity = aggresivity
def attack(self, enemy):
enemy.life_value -= self.aggresivity class Riven:
camp = 'Noxus'
def __init__(self, nickname, life_value = 80, aggresivity = 60):
self.nickname = nickname
self.life_value = life_value
self.aggresivity = aggresivity def attack(self, enemy):
enemy.life_value -= self.aggresivity g1=Garen('护花使者')
r1=Riven('兔女郎') print(r1.life_value)
g1.attack(r1)
print(r1.life_value)
3 继承
继承的基本功能是解决代码重复的问题
继承的特点:
1 继承的功能之一:解决类与类之间的代码重复问题
2 继承是类与类之间的关系,是一种什么是什么的关系
3 在子类派生出的新的属性,以自己的为准
4 在子类派生出的新的方法内重用父类的功能的方式:指名道姓法;例如:OldboyPeople.__init__,这种调用方式本身与继承是没有关系
3.1 继承的基本形式
# 继承的基本形式
class ParentClass1(object): #定义父类
pass class ParentClass2: #定义父类
pass class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
pass class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
pass print(SubClass1.__bases__) # 运行结果:(<class '__main__.ParentClass1'>,)
print(SubClass2.__bases__) # 运行结果:(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
3.2 经典类与新式类
1.只有在python2中财分新式类和经典类,python3中统一都是新式类
2.在python2中,没有显示的继承object类的类,以及该类的子类,都是经典类
3.在python2中,显式的声明继承object的类,以及该类的子类,都是新式类
4.在python3中,无论是否继承object,都默认继承object,即python3中所有类均为新式类
3.3 继承使用案例
class Animal:
x = 1
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def eat(self):
print('%s eat' %self.name) def talk(self):
print('%s say' %self.name) class People(Animal):
pass class Dog(Animal):
pass peo1 = People('alex', 18, 'male')
print(peo1.__dict__)
peo1.talk()
print(peo1.x) dog1 = Dog('yuanhao', 28, 'male') print(peo1.name)
print(dog1.name)
3.4 指名道姓的调用
通过类的方式调用类的方法,例如:Animal.__init__(self,name,age,sex)
class Animal:
x = 1
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def eat(self):
print('%s eat' %self.name) def talk(self):
print('%s say' %self.name) class People(Animal):
x = 10
def __init__(self,name,age,sex,education):
Animal.__init__(self,name,age,sex)
self.education = education def talk(self):
Animal.talk(self)
print('这是人在说话') class Dog(Animal):
pass peo1 = People('alex', 18, 'male', '小学肄业')
print(peo1.__dict__)
peo1.talk()
print(peo1.x) dog1 = Dog('yuanhao', 28, 'male') print(peo1.name)
print(dog1.name)
3.5 组合
组合:也是解决代码重用的问题,解决什么有什么的关系。
组合:一个对象的属性,来自与其他类实例化的结果;什么有什么的属性,利用组合;作业,利用了大量的组合
class OldboyPeople:
school = 'oldboy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def eat(self):
print('is eating') class OldboyStudent(OldboyPeople):
def __init__(self, name, age, sex):
OldboyPeople.__init__(self, name, age, sex)
self.course = []
def learn(self):
print('%s is learning' %self.name) class OldboyTeacher(OldboyPeople):
def __init__(self, name, age, sex, salary, title):
OldboyPeople.__init__(self, name, age, sex)
self.salary = salary
self.title = title
self.course = []
def teach(self):
print('%s is teaching' %self.name) class Course:
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price
def tell_info(self):
print('<课程名:%s 周期:%s 价格:%s>' %(self.name,self.period,self.price)) python = Course('Python','6mons',3000)
linux = Course('Lnux','3mons',2000)
bigdata = Course('BigData','1mons',1000) egon_obj=OldboyTeacher('egon', 18, 'male', 3.1, '沙河霸道金牌讲师') egon_obj.course.append(python)
egon_obj.course.append(linux)
for course in egon_obj.course:
course.tell_info() yl_obj=OldboyStudent('yanglei',28,'female')
yl_obj.course.append(python) for obj in yl_obj.course:
obj.tell_info()
3.7 继承顺序
继承的查找顺序,通过MRO列表顺序进行查找的
class J:
def test(self):
print('J')
class A(J):
pass
class E(J):
def test(self):
print('E')
pass
class H(J):
def test(self):
print('H') class G(H):
def test(self):
print('G')
pass
class B(A):
pass
class D(E):
def test(self):
print('D')
pass
class F(G):
def test(self):
print('F')
pass
class C(B,D,F):
pass c=C() #MRO列表
print(C.mro())
# [<class '__main__.C'>, <class '__main__.B'>,
# <class '__main__.A'>, <class '__main__.D'>,
# <class '__main__.E'>, <class '__main__.F'>,
# <class '__main__.G'>, <class '__main__.H'>,
# <class '__main__.J'>, <class 'object'>] #C B A D E F G H J object
3.8 子类重用父类的功能
子类重用父类的功能
1.利用指名道姓的方式进行调用
2.利用super的方式,进行调用;与继承有关,依赖于继承。
super与继承有关,依赖于继承;super,基于mro列表,向后查找
class OldboyPeople:
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def eat(self):
print('is eating')
def teach(self):
print('这是父类的teach') class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,salary,title):
# OldboyPeople.__init__(self,name,age,sex)
# 在Python2中需要写全:super(OldboyTeacher,self)
# 利用super,专门父类的属性,绑定方法
super().__init__(name,age,sex)
self.salary=salary
self.title=title def teach(self):
# OldboyPeople.teach(self)
super().teach() # 父类的teach函数属性,是绑定方法
print('%s is teaching' %self.name)
print(OldboyTeacher.mro()) egon_obj=OldboyTeacher('egon',18,'male',3.1,'沙河霸道金牌讲师')
print(egon_obj.__dict__)
egon_obj.teach()
3.9 绑定方法与非绑定方法
3.9.1 绑定到类的方法
classmethod
类方法的应用场景:方法跟类有关系,跟对象没有关系,就可以绑定到类的方法
从配置文件读取配置信息,进行实例化
import settings class MySql:
def __init__(self,host,port):
self.host = host
self.port = port # 绑定给类的装饰器
@classmethod
def from_conf(cls):
# 等价于MySql(settings.HOST, settings.PORT)
# 通过返回值,作为实例化的结果
return cls(settings.HOST, settings.PORT) def func1(self):pass conn1 = MySql('127.0.0.1',3306)
conn2 = MySql.from_conf() # 绑定方法,就是把类作为第一个参数传入
print(conn1.host, conn2.host)
classmethod,绑定到类的方法
绑定方法,绑定给对象、绑定给类;
绑定给对象,用对象来调用,就可以自动传值
绑定给类,类来调用;
3.9.2 非绑定方法
staticmethod
利用装饰器,进行非绑定方式
import settings
import uuid
class MySql:
def __init__(self,host,port):
self.host=host
self.port=port
self.id=self.create_id() @classmethod
def from_conf(cls): # 绑定给类的
# print(cls)
return cls(settings.HOST,settings.PORT)
def func1(self): # 绑定给对象的
pass
@staticmethod
def create_id(): # 非绑定方法
return str(uuid.uuid1()) conn1=MySql('127.0.0.1',3306)
conn2=MySql('127.0.0.2',3306)
conn3=MySql('127.0.0.3',3306) print(conn1.id,conn2.id,conn3.id)