进入python的世界_day27_python基础——对象动静态方法、继承、派生方法
一、动静态方法
动态就是绑定给对象的方法直接在类体代码中编写即可,对象调用会自动将对象当做第一个参数
传入,类调用有几个形参就传几个实参;静态方法就是普通的函数
意思就是动态会有人帮忙传一个参,静态就完全自己传啦
class Student:
school_name = '摆烂大学'
# 1.类中直接定义函数 默认绑定给对象 类调用有几个参数传几个 对象调用第一个参数就是对象自身
def func1(self):
print('看谁最能摆烂 真的好棒棒!!!')
# 2.被@classmethod修饰的函数 默认绑定给类 类调用第一个参数就是类自身 对象也可以调用并且会自动将产生该对象的类当做第一个参数传入
@classmethod
def func2(cls):
print('嘿嘿嘿 猜猜我是干嘛滴', cls)
# 3.普普通通的函数 无论是类还是对象调用 都必须自己手动传参
@staticmethod
def func3(a):
print('哈哈哈 猜猜我又是什么', a)
obj = Student()
# 1.绑定给对象的方法
obj.func1()
Student.func1(123)
Student.func1(Student)
# 其实就是必须得有个参数,也可以随便给
# 2.绑定给类的方法
Student.func2() # fun2(Student)
obj.func2() # func2(Student)
print(Student)
二、类的继承
1.介绍
继承是指类与类之间名称空间的传递关系,如果一个类A可以全数访问另一个类B的所有名称,或者说类A拿到了类B所有属性的访问权限,那么就称类A继承了类B。
我们可以通过子类访问到它继承的父类的所有属性
-
被继承的类被称之为父类、基类、超类
-
继承的类被称为子类、派生类
PS:一般用的比较多的就是父子类
'''单继承和多继承简单定义'''
class A:
pass
class B:
pass
class C(A): # 单继承
pass
print(C.__bases__) # 查看自己的父类 (<class '__main__.A'>,)
class D(A, B): # 多继承
pass
print(D.__bases__) # 查看自己的父类 (<class '__main__.A'>, <class '__main__.B'>)
三、继承的本质————节省代码
对象:数据与功能的结合体
类(子类):多个对象相同数据和功能的结合体
父类:多个类(子类)相同数据和功能结合体
抽象:把多个类公共的数据或功能那出来形成一个基类
继承:从上往下获取每个基类中的资源 类与父类的本质都是为了节省代码
四、名字的查找顺序
写在前头:不管哪种情况,都是先找自己名称空间的,再去找产生自己这个对象的类空间中的
1——不继承情况下名字的查找顺序
对象自身 >>> 产生对象的类 >>> (如果还找不到,会报错)
2——单继承情况下名字的查找顺序
对象自身 >>> 产生对象的类 >>> 父类
# !!!注意 如果找到了self.啥啥的一定要留意,因为对象名被传进去后又要重新再找
3——多继承情况下名字的查找顺序
对象自身 >>> 产生对象的类 >>> 父类 >>> 父类的父类(如有) 都依据从左往右
一张图看懂:

-
菱形继承查找问题:
python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。 而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则: 1.子类会先于父类被检查 2.多个父类会根据它们在列表中的顺序被检查 3.如果对下一个类存在两个合法的选择,选择第一个父类
补充(了解):
如果多继承是菱形继承,经典类与新式类的属性查找顺序不一样
经典类:深度优先,会在检索第一条分支的时候就直接一条道走到黑
新式类:广度优先,正常检索,直到最后才去找大脑
五、派生方法
super关键字
可以让子类基于父类的某个方法拓展或是增加了一些条件、打上一些属性。
class OldboyPeople:
school = 'OldBoy'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def f1(self):
print(f'{self.name} say hello')
class Student(OldboyPeople):
def choose_course(self):
print('学生%s 正在选课' % self.name)
class Teacher(OldboyPeople):
# 老师的空对象,'egon',18,'male',3000,10
def __init__(self, name, age, sex, salary, level):
# 方式2:# 调用super()会得到一个特殊的对象,该对象会参照当前类的mro,去当前类的父类里找属性
super().__init__(name, age, sex) # 调用的是方法,自动传入对象
self.salary = salary
self.level = level
def score(self):
print('老师 %s 正在给学生打分' % self.name)
print(Teacher.mro()) # [<class '__main__.Teacher'>, <class '__main__.OldboyPeople'>, <class 'object'>]
派生用法
能在继承状态下够修改父类的功能(不是修改父类,是改自己继承过来的)
比如说列表、字典、字符串等常见方法操作可以加条件框定了
class MyList(list):
def append(self, values):
if values == 'jason':
print('jason不能尾部追加')
return
super().append(values)
当我们想要做一些限制条件的时候也可以在类中添加。
obj = MyList()
print(obj, type(obj))
obj.append(111)
obj.append(222)
obj.append(333)
obj.append('jason')
print(obj)

浙公网安备 33010602011771号