类变量:
类变量是类的属性,此属性属于类,不属于此类创建的实例
说明:
类变量可以通过该类直接访问 (e.g.:Human.total_count)
类变量可以通过以该类的实例直接访问
类变量可以通过此类的对象的'__class__'属性间接访问
示例:
class Human:
total_count = 3 # 类变量,用于记录对象的个数
print(Human.total_count)
h1 = Human()
print(h1.total_count) >>>3 # 不会出错,此时实例找不到实例属性,就向上找类变量
→→Human.total_count = 1 # 会修改类变量
→→h1.total_count = 1 # 会修改实例变量##添加
→→h1.__class__.total_count = 5 # 简介修改类变量
→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
类的__slots__属性:
作用:限定一个类创建的实例只能有固定的属性(实例变量)
说明:
__slot__属性是一个列表,该表的值是字符串
含有__slot__属性的类所创建的对象没有__dict__字典
→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
类方法 @classmethod
类方法是操作类的方法,类方法属于类,不属于该类创建的对象
说明:
类方法需要使用@classmethod装饰器定义
类方法的第一个参数用来'''绑定,,类''',约定写成cls
类和对象实例都可以调用类方法
类方法不能访问此类创建的对象的属性
示例:
class A:
v = 0 # 类变量
@classmethod
def get_v(cls):
# 此方法不是实例方法,而是类方法
return cls.v
静态方法: @staticmethod
静态方法是定义在类的内部的函数,此函数作用域是类内部。
说明:
静态方法需要使用@staticmethod装饰器定义
静态方法与普通函数的定义相同,不需要传入self和cls
静态方法只能凭借该类和实例来调用
静态方法不能访问类变量和实例变量
示例:
class A:
@staticmethod
def myadd(a,b):
return a + b
print(A.myadd(1,2))
a = A()
print(a.myadd(3,4))
→→→→→→→→→→→→→→→→→→→→
继承 inheritance 和派生 derived
继承/派生:
继承是从已有的类中派生出新的了类,新类具有原来的类的数据属性和行为,并能扩展新的能力
派生则是从一个已有的类中衍生出的新类,在新的类上添加新的属性和行为
作用:
1.用继承派生机制,可以将一些共有的功能加在基类中,实现代码的共享
2.在不改变超类的代码基础上,改变原有的功能
名词:
1.(原始)基类(base class)/超类(super class)/父类(father class)
2.(派生)派生类(derived class)/子类(child class)
单继承:
语法:
class 类名(超类名):
语句块
继承说明:
任何类都是直接或间接的继承自object类
object类是一切类的超类
类内的__base__属性:
用来记录此类的基类
见:help(__builtins__)
→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→
覆盖:override
什么是覆盖
覆盖是指在有继承派生关系的类中,子类中实现了与基类(超类)同名的方法,在子类
实例调用方法时,实际调用的是子类中的覆盖版本,这种现象叫做覆盖
示例见:427test3.py
注:
实际上就是方法类会优先调用属于本类的方法,如果没有,则继承使用父类方法,若没有,
继续向上。
问题:如果覆盖已经发生,如何调用父类的同名方法呢?(↓)
super函数:
super(type,obj)
返回绑定超类的实例(要求obj必须为type类型的实例)
super() 【需要在方法内部调用】 返回绑定超类的实例,等同于super(__class__,value),
且必须在方法内调用。
作用:返回超类的实例,用超类实例来调用其自身的方法
————————————————————————————————————————
class A:
def work(self):
print('A类的work方法被调用')
class B(A):
def work(self):
print('B类的work方法被调用')
def doworks(self):
self.work()
super(B,self).work() # 用超类的方法
super().work() # 用超类的方法
b = B()
b.work()
super(B,b).work() # 可以调用B的父类中的方法
b.doworks()
————————————————————————————————————————
显式调用基类的初始化方法:
说明:当子类实现了__init__方法后,父类的__init__方法将会被覆盖,即不会再主动调用父类的
__init__方法,会引起父类属性得不到初始化,此时需要显式调用父类的初始化方法。
class Human:
def __init__(self,n,a):
self.name = n
self.age = a
print('Human类的__init__方法被调用')
def show_info(self):
print('年龄',self.age)
print('姓名',self.name)
class Student(Human):
def __init__(self,n,a,s=0):
super().__init__(n,a) # → 调用了父类的初始化属性
self.score = s
def show_info(self):
super().show_info() # → 调用父类的方法
print('成绩',self.score)