静态属性&类方法&静态方法
class Room:
tag=19
def __init__(self,name,width,length,height):
self.Name=name
self.Width=width
self.Length=length
self.Height=height
@property #静态属性可以将python定义的函数“当做”属性访问,从而提供更加友好访问方式:如不加小括号
def cal_area(self):
return "%s住的房子面积是%s" %(self.Name,self.Width*self.Height)
@classmethod #类方法,类调用自己方法,自动生成位置参数cls,无需实例化(无self),只用类级别操作时用到,无法访问实例变量,但实例能正常调用
def tell_info(cls, x):
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)
r1=Room('lee',100,100,100)
#print(r1.cal_area())
print(r1.cal_area)
print(r1.Name)
r1.wash_body('lee','alex','lll')
Room.test(1,2)
r1.tell_info(1)
静态属性:@property可以将python定义的函数“当做”属性访问,从而提供更加友好访问方式:如不加小括号
类方法:@classmethod 类调用自己方法,自动生成位置参数cls,无需实例化(无self),只用类级别操作时用到,无法访问实例变量,但实例能正常调用
静态方法:@staticmethod静态方法只是名义上的归属类管理,无法访问类变量和实例变量,是类的工具包
用组合&继承来完成一个简单的学校选择系统
import pickle
import hashlib
import time
def num():
# 用hashlib模块生成一串标识符,用来标明文件的唯一性,避免写到一个文件夹里
m=hashlib.md5()
m.update(str(time.time()).encode('utf-8'))
return m.hexdigest()
class Base:
#用pickle来构造一个存储和读取的功能,用来保存已选择课程学生的数据
def save(self):
with open(str(self.id),'wb') as f:
pickle.dump(self,f)
def read(self,):
scl=pickle.load(open(str(self.id),'rb'))
return scl
class Sclool(Base):#继承Base类以便每次实例化后,把数据存放到文件中,通过num()函数返回的字符串当做id来表明文件方便读取
def __init__(self,name,city):
self.id = num()
self.name=name
self.city=city
class Course(Base):#继承Base类以便每次实例化后,把数据存放到文件中,通过num()函数返回的字符串当做id来表明文件方便读取
def __init__(self,name,price,period,school,teacher):
self.id=num()
self.name=name
self.price=price
self.period=period
self.school=school
self.teacher=teacher
class Teacher(Base):#继承Base类以便每次实例化后,把数据存放到文件中,通过num()函数返回的字符串当做id来表明文件方便读取
def __init__(self,name,sex,age):
self.id=num()
self.name=name
self.sex=sex
self.age=age
s1=['oldboy','北京']
s2=['oldboy','上海']
c1=['linux',15,5,]
c2=['python',10,3,]
c3=['go',5,100,]
t1=['叫兽1','男',40]
t2=['叫兽2','女',45]
t3=['叫兽3','男',22]
sclools='''
选择校区:
1 oldboy 北京
2 oldboy 上海
'''
teachers='''
老师选择:
1 '叫兽1','男',40
2 '叫兽2','女',45
3 '叫兽3','男',22
'''
courses='''
课程选择:
1 linux 费用15元 周期5天
2 python 费用10元 周期3天
3 go 费用10元 周期100天
'''
while True:
menu1={'1':s1,'2':s2}
print(sclools)
sclool1=input("请选择学校所在地")
scl=Sclool(menu1[sclool1][0],menu1[sclool1][1])
scl.save()
menu3 = {'1': t1, '2': t2, '3': t3}
print(teachers)
teacher1=input("请选择老师")
tea=Teacher(menu3[teacher1][0],menu3[teacher1][1],menu3[teacher1][2])
tea.save()
menu2={'1':c1,'2':c2,'3':c3}
print(courses)
course1=input('请选择课程')
cou=Course(menu2[course1][0],menu2[course1][1],menu2[course1][2],scl,tea)
cou.save()
#用组合的方式把学校类和老师类的实例对象当做参数传入课程类对象中
print("你选择%s开始学习,价格为%s元,周期为%s天,学校是%s,%s老师授课" %(cou.read().name,cou.read().price,cou.read().period,cou.school.read().name,cou.teacher.read().name))
ls=input('1继续选择,2退出系统')
if ls==1:
continue
else:
break
输出结果:
接口继承与归一化:
1.继承基类的方法,并作出自己的改变或者扩展(代码重用)
class Animal:
def 吃(self):
pass
def 喝(self):
pass
def 拉(self):
pass
def 撒(self):
pass
class Cat(Animal):
def __init__(self,name):
self.name=name
def cry(self):
print('咪咪叫')
class Dog(Animal):
def __init__(self,name):
self.name=name
def cry(self):
print('汪汪叫')
a=Dog()
a.吃()
b=Cat()
b.吃()
2.声明某个子类兼容与某基类,定义一个接口类,子类继承接口类,并且实现接口中定义方法
#基类用@abc.abstractmethod装饰,该子类此方法必须存在,内部逻辑可有可无
#基类没用@abc.abstractmethod装饰,该子类此方法可存在可不存在,内部逻辑可有可无
import abc#接口继承模块
class jilei(metaclass=abc.ABCMeta):
@abc.abstractmethod#装饰后,继承该类后必须具备此方法才能调用
def read(self):
pass
@abc.abstractmethod
def write(self):
pass
def rood(self):
pass
class Cdrom(jilei):
def read(self):#基类用@abc.abstractmethod装饰,该子类此方法必须存在,内部逻辑可有可无
print('read')
def write(self):#基类用@abc.abstractmethod装饰,该子类此方必须存在,内部逻辑可有可无
print('write')
#def rood(self):#基类没用@abc.abstractmethod装饰,该子类此方法可存在可不存在,内部逻辑可有可无
#print('gg')
a=Cdrom()
a.write()
继承顺序的mro线性顺序列表:
class A:
def test(self)
print('A')
class B(A):
def test(self)
print('B')
class C(A):
def test(self)
print('C')
class D(B):
def test(self)
print('D')
class E(C):
def test(self)
print('E')
class F(D,E):
def test(self)
print('F')
广度优先顺序:F>D>B>E>C>A
深度优先顺序:F>D>B>A>E>C
规则:
1.子类优先于父类被检查
2.多个父类会根据他们在列表中的顺序被检查
3如果对下一个类存在的两个合法的选择,选择第一个父类
class c1:经典类
class c2(c1):经典类
class N1(object):新式类
class N2(N1):新式类
python3默认自带object新式类不用写
子类调用父类:
class Vehicle:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
def run(self):
print('开车了')
class Subway(Vehicle):
def __init__(self,name,speed,load,power,line):
Vehicle.__init__(self,name,speed,load,power)
self.name = name
self.speed = speed
self.load = load
self.power = power
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
line13=Subway('重庆地铁','10km/s',1000000,'核动力',13)
line13.show_info()
用super调用父类
class Vehicle:
Country='China'
def __init__(self,name,speed,load,power):
self.name=name
self.speed=speed
self.load=load
self.power=power
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(Subway.self).__init__(name, speed, load, power)
self.name = name
self.speed = speed
self.load = load
self.power = power
self.line=line
def show_info(self):
print(self.name,self.speed,self.load,self.power,self.line)
line13=Subway('重庆地铁','10km/s',1000000,'核动力',13)
line13.show_info()
super()==super(__class__,<first argument>)代表实例所在的类不写参数默认就是 即:super().__init__(name,speed,load,power)==super(Subway.self).__init__(name, speed, load, power)