Day18笔记
类变量
意义 |
类变量的类的属性,此属性属于类,不属于类的实例 |
作用 |
通常用来存储该类对象共 有的数据 |
说明 |
1.类变量可以通过类之间访问 |
2.类变量可以通过类的实例之间访问 |
|
3.类变量可以通过此类的对象__class__属性间 |
|
语法 |
Class 类名(继承列表): 类变量名 = 表达式 … |
示例:
class Human:
total_couth = 0 #类变量,此变量用来记录所有对象的个数
def __init__(self,n):
self.name = n
print('Human类内的类变量total_couth=',Human.total_couth)#0
#类变量可以通过类直接访问
Human.total_couth += 1
print("Human.total_couth = ",Human.total_couth)#1
#类变量可以通过类的实例直接访问
h1 = Human('小张')
print("h1.total_couth = ",h1.total_couth)#1
#此做法是为实例添加一个变量,并不是修改类变量
h1.total_couth = 100
print("Human.total_couth = ",Human.total_couth)#1
#k类变量可以通过此类的对象的__class__属性直接访问
h1.__class__.total_couth = 200
print("Human.total_couth = ",Human.total_couth)#200
类的文档字符串
意义 |
类内没有赋值给任何变量的字符串为类的文档字符串 |
类的文档字符串有类的__doc__属性绑定 |
示例class Dog:
‘’’这是类的文档字符串’’’
Pass
>>>help(Dog)
>>>dog1 = Dog()
>>>help(dog1)
类的__slots__属性
作用 |
限定一个类创建的实例只能有固定的属性(实例属性)不允许对象添加以外的属性,访问用户因错写属性的名称而发生程序错误 |
说明 |
含有__slots__属性的类所创建的实例没有__dict__属性,即此实例不用字典来存储对象的属性 |
示例:
class Student:
# 此列表让Student创建的对象只能用name和 age属性,
# 不能有其它属性
__slots__ = ['name', 'age']
def __init__(self, name, age):
self.name = name
self.age = age
s1 = Student('Tarena', 15)
print(s1.age) # 15
# s1.Age = 16 # 报错,不允添加__slots__列表以外的属性
print(s1.age) # 16?
类方法
意义 |
类方法是用来描述类的行为的方法,此方法属于类,不属于该类创建的实例 |
说明 |
1.类方法需要使用 ,@classmethod 装饰器定义 |
2.类方法至少有一个形参,第一个形参用于绑定类,约定写为’cls’ |
|
3.类实例和对象实例都可以调用类方法 |
|
4.类方法不能访问此类创建的对象的属性 |
示例:
class A:
v = 0#<<<----类变量
@classmethod
def get_v(cls):
'''此方法为类方法,cls用于绑定调用此方法的类
此方法用于返回类变量v的值'''
return cls.v
@classmethod #修改类变量
def set_v(cls,value):
cls.v=value
print(A.get_v())#0 #调用类方法返回值
A.set_v(100)
print(A.get_v())#100#修改类变量后的值
静态方法 @staticmethod
意义 |
静态方法是定义在类内的函数,此函数的作用域是类的内部 |
说明 |
1.静态方法需要使用staticmethod装饰器定义 |
2.静态方法与普通函数定义相同, 不需要传入self实例参数和cls类参数 |
|
3.静态方法只能凭借该类或类的实例调用 |
|
4.静态方法不能访问类变量和实例变量(属性) |
示例:
class A:
@staticmethod
def myadd(x,y):
return x + y
print(A.myadd(100,200))#300
a = A()
print(a.myadd(300,400))#700
小结:
实例方法, 类方法,静态方法,函数
练习:
用类来描述一个学生的信息(可以修改之前写的student类)
class Student:
....此处自己实现
学生信息有:
姓名 , 年龄 , 成绩
将这些学生对象存于列表中,可以任意添加和删除学生成绩
1)打印学生的个数
2)打印出所有学生的平均成绩
3)打印出所有学生的平均成绩
(建议用类变量存储学生的个数)
继承(inheritance) 和派生(derived)
意义 |
1.继承是指已有的类中派生出新的类,新的类具有原类的行为,并能扩展新的行为 |
||
2.派生类就是从一个已有的类繁衍生出新的类,在新的类上可以添加新的属性和行为 |
|||
作用 |
用继承派生机制,可以将一些共有功能加在基类上,实现代码共享 在不改变超类的代码的基础上改变原有的功能 |
||
名词 |
基类(base class) |
超类(super class) |
父类(father class) |
派生类(derived class)/子类 |
|||
单继承 |
单继承
语法 |
Class类名(基类名) |
说明 |
单继承是指派生类有一个基类衍生出来 |
继承说明 |
任何类都之间可间接的继承自object类 object类是一分类的超类 |
示例:
class Human:
'''此类用来描述人类的共性行为'''
def say(self,what):
print("说:",what)
def walk(self,distance):
print("走了",distance,"公里")
class Student(Human):
def study(self,subject):
print("学习",subject)
class Teacher(Human):
def teach(self,subject):
print("教了",subject)
h1 = Human()
h1.say("今天天气真好")
h1.walk(5)
print("********")
s1 = Student()
s1.walk(4)
s1.say("走的有点累")
s1.study("python")
print("*********")
t1 = Teacher()
t1.say("今天晚饭吃什么")
t1.walk(3)
t1.teach("继承/派生")
思考下列表代码做了什么事?
class MyList(list):
def insert_head(self,n):
self.insert(0,n)
myl = MyList(range(3,6))
myl.insert_head(2)
myl.append(6)
print(myl) #结果为[2,3,4,5,6]
类的__base__属性
意义 |
__base__属性用来记录此类的基类 |
示例:
class Human:
pass
class Student(Human):
pass
class Teacher(Human):
pass
Student.__base__is Human #True
内建类的继承关系见:
>>>help(__builtins__)
override覆盖
意义 |
覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法 在子类实例调用该方法时,实际调用的是子类中的覆盖版本的方法的现象较覆盖 |
示例:
class A:
'''A类'''
def work(self):
print("A.work被调用")
class B(A):
'''B类'''
def work(self):
'''work 方法覆盖了父类的work'''
print("B.work被调用")
b = B()
b.work()
a = A()
a. work()
super 函数
Super(type,obj) |
返回绑超类的实例(要求obj必须为type类型的实例) |
Super() |
返回绑定超类的实例,等同于 super(__class__,实例方法的第一参数),必须用在方法内调用 |
作用 |
返回绑定超类的实例,用超类的实例来调用其父类的覆盖方法 |
示例:
#方法1
class A:
def work(self):
print("A.work()")
class B(A):
def work(self):
print("B.work()")
b = B()
b.work() #B.work()
super(B,b).work() #A.work()
#方法2
class A:
def work(self):
print("A.work()")
class B(A):
def work(self):
print("B.work()")
def super_work(self):
'''此方法先调用一下子类的work,
再调用一下父类的work'''
self.work() # 调用自己的work
super().work() # 调用父类的work
b = B()
b.super_work()
显式调用基类的构造方法
意义 |
当子类中出现了__init__方法,基类的构造方法并不会被调用,此时需要显式调用基类的构造方法 |
示例:
class Human:
def __init__(self, n, a):
self.name = n
self.age = a
print("Human.__init__被调用")
def infos(self):
print("姓名:", self.name)
print("年龄:", self.age)
class Student(Human):
def __init__(self, n, a, s):
super().__init__(n, a) # 显式调用父类的初始化方法
self.score = s
print("Student.__init__被调用")
def infos(self):
super().infos()
print("成绩:", self.score)
# h1 = Human('小张', 18)
# h1.infos()
s1 = Student("王同学", 20, 90)
s1.infos()