静态属性,静态方法,组合,继承,衍生,继承之mro线性顺序列表,面向对象综合实例
1.静态属性(附有装饰器)
class Room: def __init__(self,name,owner,width,length,height): self.name=name self.owner=owner self.width=width self.length=length self.height=height @property def cal_area(self): return self.width*self.length r1=Room("厕所","alex",100,100,100000) r2=Room("公共厕所","yuanhao",1,1,1) print("%s住的%s总面积是%s" %(r1.owner,r1.name,r1.width*r1.length)) print("%s住的%s总面积是%s" %(r2.owner,r2.name,r2.width*r2.length)) # r1.cal_area # r2.cal_area print(r1.cal_area) print(r2.cal_area) print(r1.name) print(r2.name)
利用常规类实例计算值和利用装饰器封装函数,调用取值,让用户觉察不到数据类型的处理方法
class Volume: def __init__(self,length,width,height): self.length=length self.width=width self.height=height @property def cal_volume(self): return self.length*self.width*self.height v1 = Volume(10,20,30) print("长宽高分别是%s,%s,%s" %(v1.length,v1.width,v1.height)) print("体积是%s" %(v1.length*v1.width*v1.height)) res = v1.cal_volume print("体积是%s" %res)
2.静态方法
#静态方法: class Room: tag = 1 def __init__(self,name,owner,width,length,height): self.name = name self.owner = owner self.width = width self.length = length self.height = height @property def cal_area(self): return self.width*self.length def test(self): print("from test",self.name) @classmethod #类方法,只用于实例属性 def tell_info(cls,x): #cls为函数本身的参数,不用人为传参 print("---->",cls.tag,x) #类方法能否调用实例属性?可以 print(Room.tag) # r1 = Room("toilet", "alex",100,100,10000) # Room.tell_info(r1) #类方法:只和类捆绑,不和任何实例捆绑 Room.tell_info(10) #默认Room=cls r1 = Room("toilet", "alex",100,100,10000) r1.tell_info(100) #实例调用可传入类
静态方法
class Room: tag = 1 def __init__(self,name,owner,width,length,height): self.name = name self.owner = owner self.width = width self.length = length self.height = height @property #封装逻辑 def cal_area(self): return self.length * self.width @classmethod#自动传入类 def tell_info(cls,x): #类,函数,不能访问实例属性,静态类变量只是名义上的归属类管理,不能使用类变量和实例变量,是类的工具包 print(cls) print("-->",cls.tag,x) @staticmethod def wash_body(a,b,c): print("%s %s %s正在洗澡"%(a,b,c)) def test(x,y): print(x,y) print(Room.__dict__) r1 = Room("厕所","alex",100,100,100000) #定义类 print(r1.__dict__)
3.组合
# 组合 class Hand: pass class Foot: pass class Trunk: pass class Head: pass class Person: def __init__(self,id_num,name): self.id_num = id_num self.name = name self.hand = Hand() self.foot = Foot() self.trunk = Trunk() self.head = Head() # p1 = Person("1111","alex") # print(p1.__dict__) class School: def __init__(self,name,addr): self.name = name self.addr = addr def zhao_sheng(self): print("%s 正在招生" %self.name) class Course: def __init__(self,name,price,period,school): self.name = name self.price = price self.period = period self.school = school s1 = School("oldboy","peking") s2 = School("oldboy","nanjing") s3 = School("oldboy","Tokyo") c1 = Course("linux",10,"1h",s1) print(c1.__dict__) print(c1.school) print(s1) print(c1.school.name) #----------------------------------------------选课系统 class Hand: pass class Foot: pass class Trunk: pass class Head: pass class Person: def __init__(self,id_num,name): self.id_num = id_num self.name = name self.hand = Hand() self.foot = Foot() self.trunk = Trunk() self.head = Head() # p1 = Person("1111","alex") # print(p1.__dict__) class School: def __init__(self,name,addr): self.name = name self.addr = addr def zhao_sheng(self): print("%s 正在招生" %self.name) class Course: def __init__(self,name,price,period,school): self.name = name self.price = price self.period = period self.school = school s1 = School("oldboy","peking") s2 = School("oldboy","nanjing") s3 = School("oldboy","Tokyo") c1 = Course("linux",10,"1h",s1) msg = ''' 1 老男孩 北京校区 2 老男孩 南京校区 3 老男孩 东京校区 ''' while True: print(msg) menu = { "1":s1, "2":s2, "3":s3 } choice = input("选择学校>>") school_obj = menu[choice] name = input("课程名>>: ") price = input("课程费用>>: ") period = input("课程周期>>: ") new_course = Course(name,price,period,school_obj) print("磕碜【%s】 属于【%s】学校" %(new_course.name,new_course.school.name)) #组合方法_创建3个类:课程,老师,课程关联老师,老师管理课程 #组合应用场合:两个类本质上没有共同点,但是有关联的 #---------------------------------------------------------------------------- class Hand: pass class Foot: pass class Trunk: pass class Head: pass class Person: def __init__(self,id_num,name): self.id_num = id_num self.name = name self.hand = Hand() self.foot = Foot() self.trunk = Trunk() self.head = Head() # p1 = Person("1111","alex") # print(p1.__dict__) class School: def __init__(self,name,addr): self.name = name self.addr = addr def zhao_sheng(self): print("%s 正在招生" %self.name) class Course: def __init__(self,name,price,period,school): self.name = name self.price = price self.period = period self.school = school s1 = School("oldboy","peking") s2 = School("oldboy","nanjing") s3 = School("oldboy","Tokyo") c1 = Course("linux",10,"1h",s1) print(c1.__dict__) print(c1.school) print(s1) print(c1.school.name)
4.不同类组合的实例(动态输出多个组合结果)
class Znj: def __init__(self,word1,word2): self.word1 = word1 self.word2 = word2 class School: def __init__(self,name,addr,course): self.name = name self.addr = addr self.course = course self.znj = Znj def zhao_sheng(self): print("%s 正在招生" %self.name) def Znj(self): print("想对znj说一句%s" %self.znj) class Course: def __init__(self,name,price,period,num): self.name = name self.price = price self.period = period self.num = num c3 = Znj("123","456") c1 = Course("linux",10,"1h",c3) s1 = School("oldboy","南京",c1) s2 = School("girl",24,c1) print(c1.num.word1,c1.num.word2) #实现不同类组合! print(c3.__dict__) print(s1.__dict__) print(s2.__dict__) print(s1.course.name) #类组合就是在实例中添加另一个实例,作为参数传到类中
5.继承
class Dad: "this is a dad class" money = 10 def __init__(self,name): print("dad") self.name = name def hit_son(self): print("%s 正在打儿子" %self.name) class Son(Dad): money = 10000008 def __init__(self,name,age): self.name = name self.age = age def hit_son(self): print("from son class") Son.hit_son("self") print(Dad.__dict__) print(Son.__dict__) s1 = Son("alex",18) s1.hit_son() #实例调用hit_son() Son.hit_son("self") #类调用hit_son() print(Dad.money) print(s1.name) print(s1.__dict__) #实例字典 #父类在字典中包括更全key,value值 #子类在字典中缺少部分父类拥有的key,value值
6.继承与派生
什么时候用继承:
a)当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好。
b)当类之间有很多相同的功能,提取这些共同的功能叫做基类,用继承比较好。
继承有两种含义:1继承基类的方法,并作出自己的改变或者扩展(代码可重用);2接口继承:声明某个子类兼容与某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法
接口技术:定义父类,规定子类必须读或写,否则不能调用实例。
#接口实际是函数 #接口继承是定义一个基类,基类中实现自己函数(装饰器) # 子类中必须实现父类中方法,否则不可实例化 import abc class All_file(metaclass = abc.ABCMeta): @abc.abstractmethod def read(self): print("all_file read") @abc.abstractclassmethod def write(self): print("all_file write") class cdrom(All_file): def read(self): print("cdrom read") def write(self): print("cdrom write") class disk(All_file): def read(self): print("disk read") def write(self): print("disk write") class mem(All_file): def read(self): print("mem read") def write(self): print("mem write") m1 = mem() m1.read() m1.write()
7.继承顺序值mro线性顺序列表
class A: def test(self): print("A") pass class B(A): def test(self): print("B") pass class C(A): def test(self): print("C") pass class D(B): def test(self): print("D") pass class E(C): def test(self): print("E") pass class F(D,E): def test(self): print("D,E") pass f1 = F() #实例化 f1.test() #实例化调用函数 继承顺序 F->D->B->E->C->A
8.PY3新式类和PY2经典类
class A: def test(self): print("A") pass class B(A): # def test(self): # print("B") pass class C(A): def test(self): print("C") pass class D(B): # def test(self): # print("D") pass class E(C): # def test(self): # print("E") pass class F(D,E): # def test(self): # print("D,E") pass f1 = F() #实例化 f1.test() #实例化调用函数 新式类继承顺序 F->D->B->E->C->A # print(F.__mro__) #新式类方法 f1 = F() f1.test() #python2 经典类继承顺序 F->D->B->A->E->C
9.在子类中调用父类
class Vehicle: Country = "China" def __init__(self,name,speed,load,power): self.name = name self.speed = speed self.load = load self.power = power # self.line = line def run(self): print("开动了") class Subway(Vehicle): def __init__(self,name,speed,load,power,line): Vehicle.__init__(self,name,speed,load,power) self.line = line def show_info(self): print(self.name,self.line) def run(self): Vehicle.run(self) Vehicle.run(self) Vehicle.run(self) Vehicle.run(self) print('%s 开动啦' %self.name) line13 = Subway("13号线","30m/s","1000","电",13) line13.show_info() line13.run()
10.super调用父类方法
class Vehicle: Country = "China" def __init__(self,name,speed,load,power): self.name = name self.speed = speed self.load = load self.power = power # self.line = line def run(self): print("开动了") class Subway(Vehicle): def __init__(self,name,speed,load,power,line): # Vehicle.__init__(self,name,speed,load,power) super().__init__(name,speed,load,power) #运行super函数,调用__init__函数,可以调用到父类函数 self.line = line def show_info(self): print(self.name,self.line) def run(self): # Vehicle.run(self) super().run() #super()函数好处,1不用父类名 2不用传self参数 super().run() super().run() print('%s 开动啦' %self.name) line13 = Subway("13号线","30m/s","1000","电",13) line13.show_info() line13.run()
11.学校类创建综合实例(序列化方式存取文件)
import pickle class School: def __init__(self,name,addr): self.name = name self.addr = addr def save(self): with open("school.db","wb") as f: pickle.dump(self,f) #以序列化方式创建文件 class Course: def __init__(self,name,price,period,school): self.name = name self.price = price self.period = period self.school = school s1 = School("oldboy","北京") s1.save() # school_obj = pickle.load(open("school.db","rb")) # print(school_obj.name,school_obj.db) #以上永久建立实例 #以下取出实例 import pickle class School: def __init__(self,name,addr): self.name = name self.addr = addr def save(self): with open("school.db","wb") as f: pickle.dump(self,f) #以序列化方式创建文件 class Course: def __init__(self,name,price,period,school): self.name = name self.price = price self.period = period self.school = school school_obj = pickle.load(open("school.db","rb")) print(school_obj.name,school_obj.addr)
12.补充:深度查找方法和广度查找方法
深度优先查找顺序:A-B-D-G-I-E-C-F-G
广度优先查找顺序:A-B-C-D-E-F-G-H-I
图2 广度优先和广度优先查找方法解释图
13.面向对象综合实例
#xxx.db文件没有生成,一个类对应一个序列的操作没有实现 import pickle import hashlib import time def create_md5(): m = hashlib.md5() m.update(str(time.time()).encode("utf-8")) return m.hexdigest() id=create_md5() time.sleep(1) id1=create_md5() time.sleep(1) id2=create_md5() #每一个ID作为标识,存储文件 print(id) print(id1) print(id2) class Base: def save(self): with open("school.db","wb") as f: pickle.dump(self,f) class School(Base): def __init__(self,name,addr): self.id=create_md5() self.name=name self.addr=addr class Course(Base): def __init__(self,name,school): # self.price=price # self.period=period self.id=create_md5() self.course_name=name self.school=school class SchoolMember(Base): """ 学习成员基类 """ def __init__(self,name,age,sex,school): self.id=create_md5() self.name=name self.age=age self.sex=sex self.school=school class Lecturer(Base): def __init__(self,name,age,sex,school): self.id=create_md5() self.name=name self.age=age self.sex=sex self.school=school s1=School('oldboy','北京') s1.save() s2=School('oldboy','上海') s2.save() # c1=Course('linux',10,'1h','oldboy 北京') # c1=Course('linux',10,'1h',s1) msg=''' 1 老男孩 北京校区 2 老男孩 上海校区 ''' while True: print(msg) menu={ '北京':s1, '上海':s2, } sch_choice=menu[input('学校>>: ')] Course_name=input('课程名>>: ') Course1=Course(Course_name,sch_choice) # print(sch_choice,Course_name,Course1.school.name) print('课程【%s】属于学校【%s】【%s】'% (Course1.course_name,Course1.school.name,Course1.school.addr)) sch_choice1 = menu[input('学校(学员)>>: ')] sch_peo=SchoolMember("alex","18","female",sch_choice1) print("成员【%s】属于学校【%s】[%s]" %(sch_peo.name,sch_peo.school.name,sch_peo.school.addr)) sch_choice2 = menu[input('学校(教员)>>: ')] lec = Lecturer("wusir", "25", "male", sch_choice2) print("教员【%s】属于学校【%s】[%s]" %(lec.name,lec.school.name,lec.school.addr)) school_obj = pickle.load(open("school.db","rb")) print(school_obj.name, school_obj.addr)
f图2 面向对象综合实例作业要求
14.面向对象建立目录时文件夹分类:
bin:可执行文件
conf:配置文件,一般设置成setting.py
db:数据
lib:图书馆
log:日志模块
src:存放主逻辑