类
# 类名推荐用驼峰命名
# 类体代码在定义时就会运行,在实例化时只自动运行__init__
# 类中存放的是对象共有的数据和功能,访问地址都一样
class Student():
# 记录有多少实例化对象
count = 0
# __init__内存放是为对象初始化属性的功能,但是可以存放任意代码
# 想要在类调用时就立刻执行的代码。
def __init__(self,stu_name,stu_age,stu_gender,stu_school='abcschool'):
self.stu_school = stu_school
self.stu_name = stu_name
self.stu_age=stu_age
self.stu_gender = stu_gender
Student.count += 1
# 隐藏属性:伪装成 _类名__属性名 ,只在类定义时有用
self.__process
装饰器
装饰器是在不修改被装饰对象源代码以及调用方式的前提下为被装饰对象添加新的功能的可调用对象
类装饰器:property
可以将类中的函数“伪装成”对象的数据属性,对象在访问该特殊属性时会触发功能的执行,然后将返回值作为本次访问的结果
class People:
def __init__(self,name,weight,height):
self.name=name
self.weight=weight
self.height=height
@property
def bmi(self):
return self.weight / (self.height**2)
obj1 = People('cc',80,1.7)
print(obj1.bmi) # 27.68166089965398
property还提供设置和删除属性的功能
class Foo:
def __init__(self,val):
self.__NAME=val
@property
def name(self): # obj.name
return self.__NAME
@name.setter
def name(self,value): # obj.setter='cc'
if not isinstance(value,str):
raise TypeError(f'{value} must be str')
self.__NAME=value
@name.delet
def name(self): # def obj.name
raise PermissionError('Can not delete')
f=Foo('ll')
f.name # ll
f.name='LL' #触发name.setter装饰器对应的函数name(f,’cc')
f.name=123 #触发name.setter对应的的函数name(f,123),抛出异常TypeError
del f.name #触发name.deleter对应的函数name(f),抛出异常PermissionError
继承
python支持多继承:可以继承多个父类
class ParentClass1: #定义父类
pass
class ParentClass2: #定义父类
pass
class SubClass1(ParentClass1): #单继承
pass
class SubClass2(ParentClass1,ParentClass2): #多继承
pass
SubClass2.__bases_ # 查看继承的父类
# <class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>
继承过程中扩展功能
class People:
school = 'WHU'
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
class Student(People):
# 扩展学生的学号功能
def __init__(self,name,age,sex,id):
People.__init__(self,name,age,sex)
self.id = id
def choose_course(self):
print(f'{self.name}正在选课')
# 扩展父类功能
class Teacher(People):
# 指名道姓的跟父类要__init__方法
def __init__(self,name,age,sex,salary,level):
People.__init__(self,name,age,sex)
self.salary = salary
self.level = level
def score(self):
print(f'{self.name}正在打分')
teacher = Teacher('cc',18,'woman',1500,2)
多继承
菱形继承问题
这种继承结构下导致的问题称之为菱形问题:如果A中有一个方法,B和/或C都重写了该方法,而D没有重写它,那么D继承的是哪个版本的方法:B的还是C的?如下所示
并且,对于你定义的每一个类,Python都会计算出一个方法解析顺序(MRO)列表,该MRO列表就是一个简单的所有基类的线性顺序列表
class A(object):
def test(self):
print('from A')
class B(A):
def test(self):
print('from B')
class C(A):
def test(self):
print('from C')
class D(B,C):
pass
obj = D()
obj.test() # 结果为:from B
# 多继承属性查找顺序
print(D.mro())
# [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
在非菱形继承的情况下:深度优先遍历
在菱形继承的情况下:最后找所有类的父类