python 类
Posted lxp-never
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 类相关的知识,希望对你有一定的参考价值。
类变量
类变量就类的属性,此属性属于类,不属于此类的实例
作用:通常用来存储该类创建的对象的共有属性
说明:类变量可以通过该类和该类的实例直接访问;类变量可以通过此类的实例对象的__class__属性间接访问
1 class Human: 2 total_count = 0 # 类变量 3 def __init__(self, name): 4 print(name, ‘对象被创建‘) 5 6 print(Human.total_count) # 类直接访问类变量 0 7 h1 = Human(‘小张‘) 8 print(h1.total_count) # 0 用此类的实例可以访问类变量 9 h1.total_count = 100 # 为对象添加实例变量 10 print(h1.total_count) # 100, 优先访问对象的实例变量 11 print(Human.total_count) # 0, 访问类的类变量 12 print(h1.__class__.total_count) #0 通过此类的实例对象的__class__属性来访问类变量
类的文档字符串
类内第一个没有赋值给任何变量的字符串为类的文档字符串,类的文档字符串可以用类的 __doc__属性访问
help(Dog) #查看文档字符串
类的__doc__属性用来绑定文档字符串
类的__slots__列表
作用:限定一个类创建的实例只能有固定属性(实例属性),不允许对象添加列表以外的属性(实例变量)
说明:__slots__列表绑定一个字符串列表,含有__slots__列表的类所创建的实例对象没有__dict__属性,即此实例不用字典来存储对象的属性(实例变量)
1 class Human: 2 # 以下列表限制此类的对象只能有‘name‘ 和‘age‘ 属性 3 __slots__ = [‘name‘, ‘age‘] 4 5 def __init__(self, name, age): 6 self.name, self.age = name, age 7 8 9 h1 = Human("Tarena", 15) 10 print(h1.age) # 15 11 # h1.Age = 18 # 出错,h1对象没有Age属性,也不允许有Age属性 12 print(h1.age) # 15
类方法 @classmethod
类方法是用于描述类的行为的方法,类方法属于类,不属于类的实例
说明:类方法需要使用@classmethod装饰器定义
类方法至少有一个形参,第一个参数用于绑定类,约定写为"cls",类和该类的实例都可以调用类的方法,类方法不能访问此类创建的实例属性,
1 class A: 2 v = 0 3 @classmethod 4 def get_v(cls): # cls 用来绑定调用此方法的类 5 return cls.v # 访问类变量 6 @classmethod 7 def set_v(cls, value): 8 cls.v = value 9 print(A.get_v()) # 0 10 A.set_v(100) 11 print(A.get_v()) # 100 12 a1 = A() # 创建实例 13 print("a1.get_v() =", a1.get_v()) # 100 14 a1.set_v(200) 15 print("a1.get_v() =", a1.get_v()) # 200 16 print(‘A.get_v() =‘, A.get_v()) #200
静态方法 @staticmethod
静态方法是定义在类内部的函数,此函数的作用域是类的内部
说明:静态方法需要使用 @staticmethod装饰器定义
静态方法与普通函数定义相同,不需要传入self实例参数和cls参数,静态方法只能凭借该类或类创建的实例调用,静态方法不能访问类变量和实例变量(属性)
1 class A: 2 @staticmethod 3 def myadd(a, b): 4 return a + b 5 6 7 print(A.myadd(100, 200)) # 300 8 a = A() # 创建实例 9 print(a.myadd(300, 400)) # 700
实例方法、类方法、静态方法、函数小结
不想访问类内和实例内的变量,用静态方法
只想访问类内变量,不想访问实例变量,用类方法
即要访问内变量,也想访问实例变量用实例方法
函数与静态方法相同,只是静态方式的作用域定义在类内
继承/派生
继承是指从已有的类中派生出新的类,新类具有原类的行为,并能扩展新的行为
派生类就是从一个已有类中衍生成新类,在新类上可以添加新的属性和行为
作用:1.用继承派生机制,可以将一些共有功能加在基类中,实现代码的共享
2、在不改变基类的代码的基础上改变原有的功能
名词:基类(base class)/超类(super class)/父类(father class)
派生类(derived class) / 子类(child class)
单继承:
语法:
class 类名(基累名):
语句块
说明:单继承是指由一个基类衍生出的新的类
1 class Human: # 人类的共性 2 def say(self, what): 3 print("say:", what) 4 5 def walk(self, distance): # 走路 6 print("走了", distance, ‘公里‘) 7 8 9 class Student(Human): 10 def study(self, subject): 11 print("正在学习:", subject) 12 13 14 class Teacher(Student): 15 ‘‘‘说话,行走,教学‘‘‘ 16 def teach(self, subject): 17 print("正在教:", subject) 18 19 h1 = Human() 20 h1.say(‘天气晴了‘) 21 h1.walk(5) 22 print(‘---------------‘) 23 s1 = Student() 24 s1.walk(4) 25 s1.say(‘感觉有点累‘) 26 s1.study(‘Python‘) 27 print(‘===============‘) 28 t1 = Teacher() 29 t1.walk(6) 30 t1.say(‘吃点啥好呢‘) 31 t1.teach(‘面向对象‘) 32 t1.study(‘转魔方‘)
继承说明:python3 任何类都直接或间接的继承自object类,object 类是一切类的超类
类的__base__属性:__base__属性用来记录此类的基类
覆盖
覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法,在子类的实例调用该方法时,实际调用的是子类中的覆盖版本,这种现象叫做覆盖
1 class A: 2 def works(self): 3 print("A.works被调用") 4 5 class B(A): 6 ‘‘‘ B类继承自A类‘‘‘ 7 def works(self): 8 print("B.works被调用") 9 10 b = B() 11 b.works() # B方法被调用 12 13 # a = A() 14 # a.works() # A.works被调用
1 class A: 2 def works(self): 3 print("A.works被调用") 4 5 class B(A): 6 ‘‘‘ B类继承自A类‘‘‘ 7 def works(self): 8 print("B.works被调用") 9 10 b = B() 11 b.works() # B.works被调用 12 A.works(b) # 用类名显式调用, A.works被调用
子类对象显式调用基类(被覆盖)方法的方式:基类名.方法名(实例, 实际调用传参)
super 函数
super(cls, obj)返回绑定超类的实例(要求obj必须是cls类型的实例),
super() 返回绑定超类的实例,等同于:super(__class__, 实例方法的第一个参数),必须在方法内调用
作用:借助super() 返回的实例间接调用其父类的覆盖方法
1 class A: 2 def works(self): 3 print("A.works被调用") 4 5 class B(A): 6 ‘‘‘ B类继承自A类‘‘‘ 7 def works(self): 8 print("B.works被调用") 9 10 def super_work(self): 11 self.works() # B.works被调用 12 super(B, self).works() # A.works被调用 13 super().works() # A.works被调用 14 15 16 b = B() 17 # b.works() # B.works被调用 18 # super(B, b).works() # A.works被调用 19 b.super_work() # ... 20 # super().works() # 出错,只能在方法内调用
显式调用基类的初始化方法
当子类中实现了 __init__方法,基类的构造方法并不会被调用,def __init__(self, ...)
1 class Human: 2 def __init__(self, n, a): 3 self.name, self.age = n, a 4 print("Human的__init__方法被调用") 5 6 def infos(self): 7 print("姓名:", self.name) 8 print("年龄:", self.age) 9 10 class Student(Human): 11 def __init__(self, n, a, s=0): 12 super().__init__(n, a) # 显式调用父类的初始化方法 13 self.score = s # 添加成绩属性 14 print("Student类的__init__方法被调用") 15 16 def infos(self): 17 super().infos() # 调用父类的方法 18 print("成绩:", self.score) 19 20 s1 = Student(‘小张‘, 20, 100) 21 s1.infos()
思考题一
1 # list类里只有一个append向末尾加一个元素的方法,但没有向列表头部添加元素的方法,试想能否为列表在不改变原有类的基础上添加一个insert_head(n) 方法,实现在列表的头部(前部)添加元素 2 # 如: 3 # class MyList(list): 4 # def insert_head(self, n): 5 # ... # 需要自己添加代表 6 7 # myl = MyList(range(3, 6)) 8 # print(myl) # [3, 4, 5] 9 # myl.insert_head(2) 10 # print(myl) # [2, 3, 4, 5] 11 # myl.append(6) 12 # print(myl) # [2, 3, 4, 5, 6] 13 14 15 class MyList(list): 16 def insert_head(self, n): 17 # ... # 需要自己添加代表 18 # self[0:0] = [n] 19 self.insert(0, n) # 头插 20 21 22 myl = MyList(range(3, 6)) 23 print(myl) # [3, 4, 5] 24 myl.insert_head(2) 25 print(myl) # [2, 3, 4, 5] 26 myl.append(6) 27 print(myl) # [2, 3, 4, 5, 6]
思考题二
1 # 用类来描述一个学生的信息(可以修改之前写的Student类) 2 # class Student: 3 # .... 此处自己实现 4 5 # 学生信息有: 6 # 姓名, 年龄, 成绩 7 8 # 将一些学生的对象存于列表中,可以任意添加和删除学生信息 9 # 1) 打印出学生的个数 10 # 2) 打印出所有学生的平均成绩 11 # 3) 打印出所有学生的平均年龄 12 13 14 class Student: 15 docs = [] # 用来存储所有学生信息(类变量) 16 17 def __init__(self, n, a, s): 18 self.name, self.age, self.score = n, a, s 19 20 @classmethod 21 def add_student(cls): 22 s = Student(‘小张‘, 20, 100) 23 cls.docs.append(s) 24 s = Student(‘小李‘, 18, 98) 25 cls.docs.append(s) 26 27 @classmethod 28 def get_student_count(cls): 29 return len(cls.docs) 30 31 @classmethod 32 def get_avg_score(cls): 33 ‘‘‘ 获取所有学生的平均成绩‘‘‘ 34 total = 0.0 35 for s in cls.docs: 36 total += s.score 37 return total / len(cls.docs) 38 39 Student.add_student() # 添加学生 40 print(‘当前有%d个学生‘ % Student.get_student_count()) 41 print(‘当前学生的平均成绩是:‘, Student.get_avg_score())
思考题三
1 # 用类来描述一个学生的信息(可以修改之前写的Student类) 2 # class Student: 3 # .... 此处自己实现 4 5 # 学生信息有: 6 # 姓名, 年龄, 成绩 7 8 # 将一些学生的对象存于列表中,可以任意添加和删除学生信息 9 # 1) 打印出学生的个数 10 # 2) 打印出所有学生的平均成绩 11 # 3) 打印出所有学生的平均年龄 12 13 14 class Student: 15 def __init__(self, n, a, s): 16 self.name, self.age, self.score = n, a, s 17 18 docs = [] # 用来存储所有学生信息 19 20 def add_student(lst): 21 s = Student(‘小张‘, 20, 100) 22 lst.append(s) 23 s = Student(‘小李‘, 18, 98) 24 lst.append(s) 25 26 def get_student_count(lst): 27 return len(lst) 28 29 def get_avg_score(lst): 30 ‘‘‘ 获取所有学生的平均成绩‘‘‘ 31 total = 0.0 32 for s in lst: 33 total += s.score 34 return total / len(lst) 35 36 add_student(docs) # 添加学生 37 print(‘当前有%d个学生‘ % get_student_count(docs)) 38 print(‘当前学生的平均成绩是:‘, get_avg_score(docs))
以上是关于python 类的主要内容,如果未能解决你的问题,请参考以下文章