博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第七 其它模块及面向对象
阅读量:7079 次
发布时间:2019-06-28

本文共 25311 字,大约阅读时间需要 84 分钟。

一、xml

xml同Jason意义一样,不过较为过去式

示例m.xml内容:

2
2008
141100
5
2011
59900
69
2011
13600

搜索说明:

import xml.etree.ElementTree as ETtree = ET.parse('m.xml')root = tree.getroot()print(root.tag) #根标签print(root.attrib) #根属性print(root.text) #根内容print(root.iter('year'))  #全文搜索print(root.find('country'))  #在root的子节点查找,只查找一个print(root.findall('country'))  #在root的子节点找,找所有

结果:

遍历xml内容

import xml.etree.ElementTree as ETtree = ET.parse('m.xml')root = tree.getroot()for child in root:    print(child.tag,child.attrib,child.text)    for i in child:        print(i.tag,i.attrib,i.text)

显示结果:

遍历year节点:

import xml.etree.ElementTree as ETtree = ET.parse('m.xml')root = tree.getroot()for node in root.iter('year'):    print(node.tag,node.text)

结果:

修改文件内容,给year内容加1:

import xml.etree.ElementTree as ETtree = ET.parse('m.xml')root = tree.getroot()for node in root.iter('year'):    n_year=int(node.text)+1      node.text=str(n_year)    node.set('updated','yes') #新增更新属性    node.set('version','2.0') #新增版本号属性tree.write('n.xml')

结果:

删除等级大于20的节点:

import xml.etree.ElementTree as ETtree = ET.parse('m.xml')root = tree.getroot()for country in root.findall('country'):  #    for rank in country.findall('rank'):        #print(rank.tag,rank.attrib,rank.text)        if int(rank.text) > 20:            # country.remove(rank) #删除country的子节点            root.remove(country) #删除当前country节点tree.write('b.xml')

结果:

新增节点:

等于大于20的新增节点coincidence

import xml.etree.ElementTree as ETtree = ET.parse('m.xml')root = tree.getroot()for country in root.findall('country'):    for rank in country.findall('rank'):        if int(rank.text) > 20:            kk=ET.Element('coincidence') #添加节点            kk.text='windfall' #添加节点内容            kk.attrib={
'lottery':'22000000'} #添加节点属性 country.append(kk)tree.write('c.xml')

结果:

二、configparser

configparser修改类似于my.ini配置文件的内容,有自成的规律

示例文件:

[info1]name = 'ckl'age = 21hoppy = 'lang'is_young = Trueincome = 99999.22[info2]name = 'zld'age = 19hoppy = 'eat'is_young = Trueincome = 88888.33

获取操作

import configparser#导入模块,加载文件config = configparser.ConfigParser()config.read('ckl.ini')#打印所有标题res = config.sections()print(res)# ['info1', 'info2']#打印某个标题的所有keyops = config.options(config.sections()[0])print(ops)# ['name', 'age', 'hoppy', 'is_young', 'income']#打印某个标题的所有keyops1 = config.options('info2')print(ops1)# ['name', 'age', 'hoppy', 'is_young', 'income']#打印某个标题的所有key和valueitem_list = config.items('info1')for k,v in item_list:    print(k,v)# name 'ckl'# age 21# hoppy 'lang'# is_young True# income 99999.22#获取section的name的值,字符串格式v1 = config.get('info1','name')print(v1)# 'ckl'#获取section的age的值,int格式v2 = config.getint('info1','age')print(type(v2))print(v2)# 
# 21#获取section的is_young的值,布尔格式v3 = config.getboolean('info2','is_young')print(v3)# True#获取section的income的值,浮点格式v4 = config.getfloat('info1','income')print(v4)# 99999.22

删除操作

删除section

import configparserconfig = configparser.ConfigParser()config.read('ckl.ini')#删除section2config.remove_section('info2')config.write(open('ckl.ini','w'))  #写入文件

结果:

删除info1的age

import configparserconfig = configparser.ConfigParser()config.read('ckl.ini')#删除info1的ageconfig.remove_option('info1','age')config.write(open('ckl.ini','w'))

结果:

判断存在section及option

import configparserconfig = configparser.ConfigParser()config.read('ckl.ini')#判断是否存在sectionprint(config.has_section('info1')) #True#判断是否存在某个keyprint(config.has_option('info1','age')) # False

添加一个section

import configparserconfig = configparser.ConfigParser()config.read('ckl.ini')#添加一个section及optionconfig.add_section('info3')config.set('info3','name','wukaka')config.set('info3','age','18')config.write(open('ckl.ini','w')) #添加内容必须是字符串格式

结果:

 三、hashlib

1.hash是一种算法在python3以后,代替了MD5和sha模块,主要是:SHA1,SHA224,SHA256,SHA512,MD5等,传入内容,得到一串hash值

2.hash特点:

传入内容一样,得到值一样;不能又hash值反解内容;hash算法不变情况下,值一样。

import hashlibm5 = hashlib.md5()m5.update('nihao'.encode('utf8'))print(m5.hexdigest())# 194ce5d0b89c47ff6b30bfb491f9dc26m6 = hashlib.md5()m6.update('ni'.encode('utf8'))m6.update('hao'.encode('utf8'))print(m6.hexdigest())# 194ce5d0b89c47ff6b30bfb491f9dc26#使用md5算法,无论update多少次,内容一样,结果就一样

 如何校验文件?

import hashlibm5 = hashlib.md5()with open('b.xml','r') as fread:    for line in fread:        m5.update(line.encode('utf8'))print(m5.hexdigest())# 8cb5a607e7803fd931112588e20e1f46#不推荐如此使用,耗费内存m6 = hashlib.md5()with open('b.xml','r') as fread:    m6.update(fread.read().encode('utf8'))print(m6.hexdigest())# 8cb5a607e7803fd931112588e20e1f46

hashlib好用,但是可以撞库来反解,这个时候就需要加盐了salt

import hashlibh8 = hashlib.sha256('zthhk'.encode('utf8')) #add salth8.update('nihao'.encode('utf8'))print(h8.hexdigest())# 6eab55b060e7bc08c849a0b1405f4e7720271f10b8832b82a4c76ac47470c27c

hmac用法根其它类似,但是起始必须加盐

import hmach6 = hmac.new('bakayaro'.encode('utf8')) #类似加盐h6.update('nihao'.encode('utf8'))print(h6.hexdigest())# 6850656a1a3705600568152ff13e1195h7 = hmac.new('bakayaroni'.encode('utf8'))h7.update('hao'.encode('utf8'))print(h7.hexdigest())# d4891513a12338b58618516014ac9b25'''虽然两次的总的字符串内容一致,但结果却不一样。这是因为,生成值的时候,先匹配加盐的部分,再匹配update内容的部分,第一部分不一致,结果当然不一样'''

 四、subprocess

运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。

subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。

subprocess.call()

父进程等待子进程完成
返回退出信息(returncode,相当于Linux exit code)

subprocess.check_call()

父进程等待子进程完成
返回0
检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try…except…来检查

subprocess.check_output()

父进程等待子进程完成
返回子进程向标准输出的输出结果
检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。

import subprocessres1 = subprocess.Popen('ls /Users/kindle/Desktop/',shell=True,stdout=subprocess.PIPE)res2 = subprocess.Popen('grep txt$',shell=True,stdin=res1.stdout,stdout=subprocess.PIPE)print(res2.stdout.read())#这样做的好处是,第一个数据流可以和第二个数据流交互,并且交给grep

结果:

五、面向对象

对象是特征与功能的结合体;类是一系列对象相似特征与功能的结合体。

class WaterStaff:    company = 'WaterLand'  #类的数据属性(静态属性)    def work(self):   #类的函数属性(动态属性)        print('we are working')    def sleep(self):        print('go home and sleep')#从本质上查看类的所有属性,print(WaterStaff.__dict__)#访问类的属性print(WaterStaff.company)print(WaterStaff.sleep)# WaterLand# 
#新增类的属性WaterStaff.company = 'CKL'print(WaterStaff.company)# CKL#修改类的属性WaterStaff.tech = 'niux'print(WaterStaff.tech)# niux#删除类的某个属性del WaterStaff.tech

对象

#产生程序中的对象:类名加括号,调用类,产生一个该类的实际存在的对象,该调用过程称为实例化,产生的结果又可以称为实例。obj1 = WaterStaff()

对象实例化

class WaterStaff:    company = 'WaterLand'    def __init__(self,name,age,gender): #在实例化时,产生对象后执行        self.name = name        self.age = age        self.gender = gender        #上面实际就是如下:        # obj1.name = '雪山人'        # obj1.age = 25        # obj1.gender = 'male'    def work(self):        print('we are working')    def sleep(self):        print('go home and sleep')obj1 = WaterStaff('雪山人',25,'male')#执行两步#1.先产生空对象obj1#2.WaterStaff.__init__(obj1,'雪山人',25,'male'),这里self就是对象本身print(obj1.__dict__)# {'name': '雪山人', 'age': 25, 'gender': 'male'}

 对象属性操作

#修改属性obj1.name = '森林人'print(obj1.name)# 森林人#新增属性obj1.car = 'horse'print(obj1.car)# horse#当然也可以如下修改obj1.__dict__['age'] = 22print(obj1.age)# 22print(obj1.__dict__)# {'name': '森林人', 'age': 22, 'gender': 'male', 'car': 'horse'}

 __init__不仅可以为对象初始化属性,还可以定时任何方法

class WaterStaff:    company = 'WaterLand'    def __init__(self,name,age,gender):        #如果name不是字符串,就抛出异常        if not isinstance(name,str):            raise TypeError('name must be a tye of string')        self.name = name        self.age = age        self.gender = gender    def work(self):        print('we are working')    def sleep(self):        print('go home and sleep')obj1 = WaterStaff(889,25,'male')

__init__()函数return None 

类的数据属性(静态属性)

class WaterStaff:    company = 'WaterLand'    def __init__(self,name,age,gender):        #如果name不是字符串,就抛出异常        if not isinstance(name,str):            raise TypeError('name must be a tye of string')        self.name = name        self.age = age        self.gender = gender    def work(self):        print('we are working')    def sleep(self):        print('go home and sleep')obj1 = WaterStaff('雪山人',25,'male')obj2 = WaterStaff('森林人',33,'male')obj3 = WaterStaff('原野人',22,'female')#对象可以访问类的数据属性(静态属性);结论:类的数据属性共享给所有对象使用,id一样print(obj1.company,id(obj1.company))print(obj2.company,id(obj2.company))print(obj3.company,id(obj3.company))print(WaterStaff.company,id(WaterStaff.company))# WaterLand 4368851632# WaterLand 4368851632# WaterLand 4368851632# WaterLand 4368851632

类的函数属性(动态属性)

class WaterStaff:    company = 'WaterLand'    def __init__(self,name,age,gender):        #如果name不是字符串,就抛出异常        if not isinstance(name,str):            raise TypeError('name must be a tye of string')        self.name = name        self.age = age        self.gender = gender    def work(self):        print('%s are working' %self.name) #objx.name    def sleep(self):        print('go home and sleep')obj1 = WaterStaff('雪山人',25,'male')obj2 = WaterStaff('森林人',33,'male')obj3 = WaterStaff('原野人',22,'female')WaterStaff.work(obj1)WaterStaff.work(obj2)WaterStaff.work(obj3)# 雪山人 are working# 森林人 are working# 原野人 are working

绑定方法

class WaterStaff:    company = 'WaterLand'    def __init__(self,name,age,gender):        #如果name不是字符串,就抛出异常        if not isinstance(name,str):            raise TypeError('name must be a tye of string')        self.name = name        self.age = age        self.gender = gender    def work(self):        print('%s are working' %self.name) #objx.name    def sleep(self):        print('go home and sleep')obj1 = WaterStaff('雪山人',25,'male')obj2 = WaterStaff('森林人',33,'male')obj3 = WaterStaff('原野人',22,'female')print(obj1.work)print(obj2.work)print(obj3.work)print(WaterStaff.work)#除了类本身,其它对象的函数属性,都是绑定给其本身,绑定方法# 
>#
>#
>#
#绑定方法:绑定给谁,就由谁来调用,谁来调用就把"谁"本身当做第一个参数传入obj1.work() #WaterStaff.work(obj1)# 雪山人 are working

 python3的类型

#python3 类型就是类l1 = list()l2 = list()l1.append(3)  #list.append(l1,3)print(l1)   # [3]print(l2)   # []

 属性访问顺序

class WaterStaff:    company = 'WaterLand'    def __init__(self,name,age,gender):        #如果name不是字符串,就抛出异常        if not isinstance(name,str):            raise TypeError('name must be a tye of string')        self.name = name        self.age = age        self.gender = gender    def work(self):        print('%s are working' %self.name) #objx.name    def sleep(self):        print('go home and sleep')obj1 = WaterStaff('雪山人',25,'male')obj2 = WaterStaff('森林人',33,'male')obj3 = WaterStaff('原野人',22,'female')#访问实例属性print(obj1.__dict__)  #{'name': '雪山人', 'age': 25, 'gender': 'male'}print(obj1.company) # WaterLand#修改obj1的数据属性obj1.company = 'LandW'print(obj1.company)  #LandWprint(obj2.company)  #WaterLand#修改类本身的数据属性WaterStaff.company = 'wukaka'print(obj1.company) #LandW  #obj1已经修改了自己的数据属性print(obj2.company) #wukaka

 类交互:

#怪物牛class BullEv:    # 怪物牛名称、血量、攻击力    def __init__(self,nickname,blvom=100,aggressivity=80):        self.nickname = nickname        self.blvom = blvom        self.aggressivity = aggressivity    #攻击技能,血量等于自己攻击力减去对方血量    def attack(self,rival):        rival.blvom-=self.aggressivity#怪物蜘蛛class SpiderEv:    #怪物蜘蛛名称、血量、攻击力    def __init__(self,nickname,blvom=80,aggressivity=100):        self.nickname = nickname        self.blvom = blvom        self.aggressivity = aggressivity    # 攻击技能,血量等于自己攻击力减去对方血量    def attack(self,rival):        rival.blvom -= self.aggressivityB1=BullEv('wukaka')S1=SpiderEv('Bengde')#攻击前血量print('attack before ------>',S1.blvom)B1.attack(S1)#攻击后血量print('after attack------->',S1.blvom)

结果:

 上面类有重复代码,如何解决?那么久看看类的继承

 类的继承

class ParentClass1: #定义父类    passclass ParentClass2: #定义父类    passclass SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass    passclass SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类    pass

继承:

#继承一个父类print(SubClass1.__bases__) #(
,)#继承两个父类print(SubClass2.__bases__) #(

继承与重用

人、鸟、兔子,都有吃、叫、睡觉的功能创建三个类

class Mankind:    def eat(self):        print("eat something")    def talk(self):        print("talk something")class Bird:    def eat(self):        print("eat something")    def talk(self):        print("talk something")class Rabbit:    def eat(self):        print("eat something")    def talk(self):        print("talk something")M1 = Mankind()M1.eat()B1 = Bird()B1.eat()

运行结果:

继承父类

问题:吃、说的功能重复代码,是否可以继承?改写如下:

class Animal:    def eat(self):        print("eat something")    def talk(self):        print("talk something")class Mankind(Animal):    passclass Bird(Animal):    passclass Rabbit(Animal):    passM1 = Mankind()M1.eat()B1 = Bird()B1.eat()

结果:

问题二、每个子类应该有自己的名字年龄等信息,修改如下:

class Animal:    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = genderclass Bird(Animal):    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = genderclass Rabbit(Animal):    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = genderM1 = Mankind('wukaka',33,'male')M1.eat()B1 = Bird('flygo',3,'female')B1.eat()

运行结果:

问题三、这三个子类有共同的属性名字、年龄,性别等,重写如下:

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    passclass Bird(Animal):    passclass Rabbit(Animal):    passM1 = Mankind('wukaka',33,'male')M1.eat()B1 = Bird('flygo',3,'female')B1.eat()

结果相同:

 重用

人类还有国籍,所以定义如下:

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        self.name = name        self.age = age        self.gender = gender        self.native = nativeclass Bird(Animal):    passclass Rabbit(Animal):    passM1 = Mankind('wukaka',33,'male','china')print(M1.__dict__)  #{'name': 'wukaka', 'age': 33, 'gender': 'male', 'native': 'china'}M1.eat()B1 = Bird('flygo',3,'female')B1.eat()

这样,如下部分就与父类重复:

self.name = name        self.age = age        self.gender = gender

改写如下:

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        Animal.__init__(self,name,age,gender) #改写部分        self.native = nativeclass Bird(Animal):    passclass Rabbit(Animal):    passM1 = Mankind('wukaka',33,'male','china')print(M1.__dict__)  #{'name': 'wukaka', 'age': 33, 'gender': 'male', 'native': 'china'}M1.eat()B1 = Bird('flygo',3,'female')B1.eat()

这样实际上指明父类调用,根继承无关,结果:

派生新的属性

人有一个自己说的方法,如下:

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        Animal.__init__(self,name,age,gender) #改写部分        self.native = native    def takl(self):        print('*** a chinese man is saying')class Bird(Animal):    passclass Rabbit(Animal):    passM1 = Mankind('wukaka',33,'male','china')print(M1.__dict__)  #{'name': 'wukaka', 'age': 33, 'gender': 'male', 'native': 'china'}M1.eat()M1.takl()B1 = Bird('flygo',3,'female')B1.eat()

结果:

如果人talk的方法也想用父类的talk呢?

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        Animal.__init__(self,name,age,gender) #改写部分        self.native = native    def takl(self):        Animal.talk(self)  #调用父类的        print('*** a chinese man is saying')class Bird(Animal):    passclass Rabbit(Animal):    passM1 = Mankind('wukaka',33,'male','china')print(M1.__dict__)  #{'name': 'wukaka', 'age': 33, 'gender': 'male', 'native': 'china'}M1.eat()M1.takl()B1 = Bird('flygo',3,'female')B1.eat()

结果:

组合

一个人可以有多个房子,房子有地址、面积、价格,一个鸟也可以有多个窝,窝也有地址、面积、价格等,如下:

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native,house_addr,house_area,house_price):        Animal.__init__(self,name,age,gender)        self.native = native        self.house_addr = house_addr        self.house_area = house_area        self.house_price = house_price    def takl(self):        Animal.talk(self)        print('*** a chinese man is saying')class Bird(Animal):    def __init__(self,name,age,gender,house_addr,house_area,house_price):        Animal.__init__(self,name,age,gender)        self.house_addr = house_addr        self.house_area = house_area        self.house_price = house_priceclass Rabbit(Animal):    passM1 = Mankind('wukaka',33,'male','china','pudong','120','12000000')print(M1.__dict__)B1 = Bird('flygo',3,'female','nanhui','0.01','10')print(B1.__dict__)

运行:

{
'name': 'wukaka', 'age': 33, 'gender': 'male', 'native': 'china', 'house_addr': 'pudong', 'house_area': '120', 'house_price': '12000000'}{
'name': 'flygo', 'age': 3, 'gender': 'female', 'house_addr': 'nanhui', 'house_area': '0.01', 'house_price': '10'}

这里人的房子和鸟的窝就出现重复代码,如果人有多个房子,鸟有多个窝呢?如何实现?

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        Animal.__init__(self,name,age,gender)        self.native = native        #定义house列表        self.house = []    def takl(self):        Animal.talk(self)        print('*** a chinese man is saying')class Bird(Animal):    def __init__(self,name,age,gender,):        Animal.__init__(self,name,age,gender)        #定义house列表        self.house = []#定义house类class House:    #定义house_addr,house_area,house_price    def __init__(self,house_addr,house_area,house_price):        self.house_addr = house_addr        self.house_area = house_area        self.house_price = house_price    #定义个函数属性,来显示house相关信息    def show_info(self):        print("house address: %s house area: %s house price %s" %(self.house_addr,self.house_area,self.house_price))class Rabbit(Animal):    pass#实例化第一个househouse1 = House('pudong','109','11000000')#实例化第二个househouse2 = House('putuo','98','9900000')M1 = Mankind('wukaka',33,'male','china')#为人类添加两个houseM1.house.append(house1)M1.house.append(house2)print(M1.__dict__)# {'name': 'wukaka', 'age': 33, 'gender': 'male', 'native': 'china', 'house': [<__main__.House object at 0x109dfa048>, <__main__.House object at 0x109dfa080>]}#循环人类house,也就是对象house1和house2for obj in M1.house:    obj.show_info() #调用对象函数

结果:

组合实现了不同类有相同的属性,但不需要从父类继承的操作。

继承原理

单继承说明

class A:    def f1(self):        print("A.f1")    def f2(self):        self.f1()class B(A):    def f1(self):        print("B.f1")obj_b = B()obj_b.f2()

结果:

B.f1

分析:1.初始化类B。2.调用B类的实例化对象,运行方法f2()。3.找B类f2(),没有找到,则找继承的父类A。4.A类有方法f2(),调用方法f2,f2()则调用self.f1()。self本身就是B类,所以查找B的方法f1()有找到,则执行,结果就是B.f1

super 调用父类

super 调用父类静态属性

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        # Animal.__init__(self,name,age,gender) #这是直接调用父类的,不是继承        # super() 是父类对象的实例        # print(super().__init__) #实例化父类,绑定方法,绑定其本身,所以调用父类的新写法        super().__init__(name,age,gender) #其本身已经是绑定方法,所以不需要self        self.native = native    def takl(self):        Animal.talk(self)  #调用父类的        print('*** a chinese man is saying')M1 = Mankind('wukaka',33,'male','china')M1.eat()

结果:

wukaka eat something

super 调用父类动态属性

class Animal:    def __init__(self,name,age,gender):        self.name = name        self.age = age        self.gender = gender    def eat(self):        print("%s eat something" %self.name)    def talk(self):        print("talk something")class Mankind(Animal):    def __init__(self,name,age,gender,native):        # Animal.__init__(self,name,age,gender) #这是直接调用父类的,不是继承        # super() 是父类对象的实例        # print(super().__init__) #实例化父类,绑定方法,绑定其本身,所以调用父类的新写法        super().__init__(name,age,gender) #其本身已经是绑定方法,所以不需要self        self.native = native    def takl(self):        # Animal.talk(self)  #调用父类的动态属性,不是继承        super().eat() #super 调用父类动态属性的写法        print('*** a chinese man is saying')M1 = Mankind('wukaka',33,'male','china')M1.eat()

结果:

wukaka eat something

 区别:super()依赖于继承,而直接调用不依赖继承

Animal.talk(self)  #不依赖父类继承        super().eat() #super 依赖父类继承

 super() 查找的是MRO列表:

[
,
,
]

关于MRO列表查找疑惑

class A:    def test(self):        super().test()class B:    def test(self):        print("B")class C(A,B):    def test(self):        print("C")obj_a = A()obj_a.test()

运行:

分析:1.实例化A类。2.A类对象调用动态属性test()。3.A类的test调用super().test(),也就是父类的test(),而A类没有父类,所以报错。

如果这样运行: 

class A:    def test(self):        super().test()class B:    def test(self):        print("B")class C(A,B):    passobj_c = C()obj_c.test()

会不会报错?答案是不会,而且结果是

B

是不是迷惑了?分析如下:

1.实例化C类。2.实例化对象调用test。3.C类没有test,找父类A,父类A有test。4.A类调用test的时候调用的是super().test(),这时候,super()就不是找父类了,而是查找MRO列表的顺序,接下来查找B类,B类有方法test(),所以运行B类的test

print(C.mro())# [
,
,
,
]

classmethod 

classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。

看一个示例:

class Mysql:    def __init__(self,host,port):        self.host = host        self.port = portconn1=Mysql('127.0.0.1',3306)print(conn1.port,conn1.host)

运行结果:

如果每次都需要传入地址、端口等参数,很麻烦,有没有办法可以从配置文件中读取?

配置文件内容:

HOST='10.2.3.4'PORT=8898

代码:

import settingsclass Mysql:    def __init__(self,host,port):        self.host = host        self.port = port    @classmethod    def from_conf(cls): #这个方法绑定给类        return cls(settings.HOST,settings.PORT)conn1=Mysql('127.0.0.1',3306)print(conn1.port,conn1.host)conn2=Mysql.from_conf()#Mysql.from_conf是绑定方法,绑定给谁就给谁用,给谁用就把自己当做第一个参数print(conn2.host,conn2.port)

运行结果:

方法绑定说明

import settingsclass Mysql:    def __init__(self,host,port):        self.host = host        self.port = port    @classmethod    def from_conf(cls): #绑定给类的方法        return cls(settings.HOST,settings.PORT)    def func1(self): #绑定给对象的方法        passconn1=Mysql('127.0.0.1',3306)# print(conn1.port,conn1.host)# conn2=Mysql.from_conf()# #Mysql.from_conf是绑定方法,绑定给谁就给谁用,给谁用就把自己当做第一个参数# print(conn2.host,conn2.port)print(conn1.from_conf)print(conn1.func1)

结果说明:

staticmethod

import settingsimport uuidclass Mysql:    def __init__(self,host,port):        self.host = host        self.port = port        self.id = self.create_id()    @staticmethod    def create_id(): #普通方法,既不绑定给对象,也不绑定给类        return uuid.uuid1()conn1=Mysql('127.0.0.1',3306)conn2=Mysql('127.0.0.1',3306)conn3=Mysql('127.0.0.1',3306)print(conn1.id,conn2.id,conn3.id)print(Mysql.create_id) #普通函数print(conn1.create_id) #普通函数

结果:

class School:    def __init__(self,school_name,school_address):        self.school_name = school_name        self.school_address = school_addressclass Course(School):    def __init__(self,course_name,course_period,couse_price,course_outline):        self.course_name = course_name        self.course_period = course_period        self.course_price = couse_price        self.course_outline = course_outline    def get_school(self,school):        return school.__dict__class ClassG(Course):    def __init__(self,class_name):        self.class_name = class_name    def get_course(self,course):        return (course.__dict__,self.class_name)class Student(ClassG):    def __init__(self,student_name):        self.student_name = student_nameclass Teacher(ClassG):    def __init__(self,teacher_name,):        self.teacher_name = teacher_nameclass TeachRecord:    passclass StudyRecord:    passs1=School('mazhu','pudong')c1=Course('python',120,8990,[4,6,7,8])g1=ClassG('19s')st1=Student('whb')print(st1.get_course(g1))

 

转载于:https://www.cnblogs.com/ckl893/p/7002199.html

你可能感兴趣的文章
2018LinuxCon,开源界的大咖们来了,赶紧行动!
查看>>
10月24日程序员关爱日
查看>>
python函数定义
查看>>
服务器的安装
查看>>
如何优雅的处理异常(java)?
查看>>
VRRP 虚拟冗余路由协议
查看>>
express不是内部或外部命令
查看>>
通过反射获取成员方法并使用
查看>>
String StringBuffer StringBuilder
查看>>
bash的工作特性及命令状态返回查询
查看>>
Samba服务共享(匿名用户访问、本地用户访问、虚拟用户访问)
查看>>
HttpServletResponse输出乱码的问题
查看>>
你真的很熟分布式和事务吗?
查看>>
基于ThreadPoolExecutor实现工作引擎参考
查看>>
Go语言的基本数据类型
查看>>
WEB测试:***apache
查看>>
42 个移动端启动页面优化 Tips
查看>>
Egret之ProtoBuf安装
查看>>
Cocos2d-x3.0游戏实例《别救我》目录
查看>>
我的友情链接
查看>>