day 28
类是对属性和方法的封装,可以理解为模版,通过对模型实例化可以实现调用这个类的属性和方法。比如创建一个随机森林类,然后就可以调用它的训练和预测方法。
一个常见的类的定义包括了:
1、关键字class
2、类名
3、语法固定符号冒号(:)
4、一个初始化函数_init_(self)
注意:init左右各有两个下划线——,需要传入self 这个特殊的参数。
Pass 占位符和缩进
class ClassName:# 类名通常遵循大驼峰命名法(UpperCamelCase)单词的首字母大写,class 是定义类的关键词#类的代码(包含属性定义、方法定义等)pass # pass 是一个占位符,表示这里暂时没有任何内容。class ClassName: # 类名通常遵循大驼峰命名法 (UpperCamelCase),即每个单词的首字母都大写,# # 类的代码块 (可以包含属性定义、方法定义等)# pass # pass 是一个占位符,表示这里暂时没有任何内容
许多时候,当规划好准备写一个函数、或者一个类,关键词定义后,会先用pass 占位,避免 运行错误,等到想好些什么再去不补充。
比如def 、class 这些定义的关键词后,必须有一个占据缩进位置的代码块。
还有下面这些依赖缩紧的语句,都可以用pass 占位。# 条件语句
x=10
if x>5:pass
else:print ("x is not greater than 5")
# 循环语句
for i in range(3):pass
try:# 尝试执行的代码print("hhh")
except SomeException:pass# 异常处理代码
finally:pass总结:python 通过缩进来定义代码块的结构。当解释器遇到像def,class,if , for 这也样的语句,并且后面跟冒号时,他就期望接下来会有一个或多个缩进的语句来构成这个代码块。如果他没有找到任何缩进的语句。它就无法确定这个结构的范围,因此会抛出indentationError 异常。
pass 语句的存在就是为了解决这个问题:她本身不执行任何操作,但它是一个有效的python语句。所以,当你需要一个语法上存在的代码块,但是暂时又不想在其中放入任何实际的逻辑时,pass就是一个完美的占位符,她告诉解释器:这里有一个代码块,但是她什么不做。
类的初始化方法
初始化方法又叫构造方法、特殊方法
类的两种方法
1、初始化方法
2、普通放大
class Teacher:def __init__(self):self.name="susan"self.subject="python"self.age=30
teacher=Teacher()
print(teacher.name)class Teacher:def __init__(self,name,age):self.name=nameself.subject="python"self.age=age
teacher=Teacher("susan",30)
print(teacher.name)
print(teacher.age)
print(teacher.subject)其中,self.xx 是用来表明这个属性,归属性这个类自己的self。比如self.name,就是代表着:自己的名字,self等于自己,这个self指向类的实例化地址,传入的self.xx是他的属性。以后要是用它自己的属性值,即使是从外界参数传入,前面也必须加上self.xx,否则传入的参数没价值。类的普通方法
除了init 方法,(初始化方法,又名构造方法)还包含一些普通方法(自己定义)
普通方法和init方法的差别在于,init方法是类的构造方法,当创建对象时,会自动调用init 方法。只要你创建这个类的对象了,这个init 函数就会执行。
普通方法是只有你调用类的这个方法的时候,函数次才执行。class Teacher:def __init__(self):self.name="susan"self.subject="python"self.age=30def teach_lesson(self):print("上课中")def criticize(self):print ("批评人")
t=Teacher()
t.teach_lesson()
t.criticize()
print(t.name)
类的继承
类已经是比较优秀的封装了,封装了函数、封装了属性
如同装饰器进一步封装了函数的可复用的功能,装饰器函数封装了函数
那么有没有东西可以一步封装类呢?这就引出了类的继承。
在面向对象编程中,继承允许一个类继承另一个类(父类)的属性和方法,从而实现代码复用和功能扩展。子类可以:
1、复用父类的代码(无需重新实现)
2、重写父类的方法(修改或增强功能)
3、添加新的方法和属性(扩展功能)
# 先沿用之前定义的teacher类
class Teacher:def __init__(self,name,subject,age):self.name=nameself.subject=subjectself.age=agedef teach_lesson(self):print(f"{self.name}正在教{self.subject}")def criticize(self,student_name):print(f"{self.name}正在批评学生{student_name}")# 继承Teacher 类,起名特教教师
class MasterTeacher(Teacher):def __init__(self,name,subject,age,experience_years):# 调用父类的构造方法初始化基本属性super().__init__(name,subject,age)# 4、此时子类自动拥有了父类的属性和方法# 添加子类特有的属性self.experience_years=experience_years# 重写父类方法,增强功能-----如果子类定义了与父类同名的方法,子类实例会优先调用子类的方法def teach_lesson(self):print(f"{self.name}正在教{self.subject}")# 新增子类特有的方法def give_lecture (self,topic):print(f"{self.name}正在给学生讲解{topic}")
# 创建子类实列
master=MasterTeacher("高教授","数学",30,10)
# 调用继承的方法
master.teach_lesson()
master.criticize("李同学")
# 调用子类特有的方法
master.give_lecture("导数")# super ()函数,除了在构造方法中使用,还可以在其他方法中使用
# 定义一个父类
class Animal:def __init__(self,name,age):self.name=nameself.age=agedef speak(self):print(f"{self.name}发出声音")
class Dog(Animal):def speak(self):super().speak()print("汪汪")
dog=Dog("旺财",3)
dog.speak()
所以重写父类的方法,也包含2种:
1、直接重写:本质是会优先用子类的同名方法,完全替代父类方法,父类逻辑不会执行。
2、使用supper() 重写,保留父类方法分核心逻辑,并在其基础上扩展。
@ 浙大疏锦行