【10月更文挑战第14天】
魔法方法值方法在某种情况下会自动执行
方法是只有调用下我们才会执行,但是魔法方法的话是在某种特殊的情况下会自动进行执行的
下面的析构函数和构造函数都是魔法方法
构造函数---初始化方法
格式:def init(self): 注意这里是两个下划线
作用:在创建对象的时候就会自动执行
class Student:
#姓名、年龄、成绩---描述----属性
def fun(self,name,age,grade):#接收传入的数据
self.name=name
self.age=age
self.grade=grade
#睡觉、吃饭、学习---动作、行为---方法 def 方法名()
#self接受对象信息,即seif=对象
def sleep(self):
print(f'{self.name}正在睡觉')
#在类里面进行实例属性的调用
def eat(self):
print(f'{self.name}正在吃东西')
def study(self):
print(f'{self.name}正在学习')
class Test:
def __init__(self,name,age):
print("这是一个初始化方法")
t=Test()
#这是一个初始化方法
#我们在创建对象的时候这个init函数会自动执行的,自动进行初始化操作
#如果在__init__中有定义形参,那么创建对象时就要传递实参
#对于对象中都要使用到的通用属性的话,我们就会将这些属性放到__init__函数进行初始化操作
#伴随着对象的创建,那么这个对象的基本属性就初始化好了
#像是上面的fun函数我们必须先调用我们才能实现这个对象属性的初始化操作
#但是现在的话我们是不需要进行调用这个init函数
#我们对象一创建好这个init函数就自动进行调用了
#将一些必备的属性放在init函数中,创建对象就直接初始化好了,
将一些常用的属性放到init函数中,然后我们在创建对象的时候就能进行对象属性的初始化了
析构函数
格式:def del__(self)
在实例对象被销毁的时候执行
在对象的生命周期快到了的时候就将对象所占的空间进行清空的操作
就是释放内存空间
class Test:
#构造函数
def __init__(self,name):
self.name=name#这个self就是指向的对象
print("这是一个初始化方法")
#析构函数--对对象进行销毁的操作
def __del__(self):
print(f'{self.name}进行销毁')
t=Test("张三")
print("程序执行完毕")
del t
'''
这是一个初始化方法
程序执行完毕
张三进行销毁
'''
#我们只有将这个t这个对象进行销毁了,才会进行这个析构函数
#如果这个t没有被回收的话是不会进行析构函数的
#我们这里是不会进行这个析构函数内的打印操作的,但是在paycharm中是会进行的
#手动的删除del执行时间是在程序结束之前进行的
py文件所有代码执行完就会自动执行析构函数
我们在创建对象t的时候在这个类括号中输入了张三
然后张三就别传到了init函数进行属性的初始化操作了
方法是只有调用下我们才会执行,但是魔法方法的话是在某种特殊的情况下会自动进行执行的
除了自动删除操作,我们还能使用手动删除操作del进行删除操作
输出魔法方法
格式: **str(self):设置print输出对象名时显示的内容
class Test:
#构造函数
def __init__(self,name):
self.name=name#这个self就是指向的对象
print("这是一个初始化方法")
#析构函数--对对象进行销毁的操作
def __del__(self):
print(f'{self.name}进行销毁')
#设置print输出对象名时显示的内容
def __str__(self):
return "这是一个魔法方法__str__设置的"
t1=Test("张三")
print(t1)
#这是一个魔法方法__str__设置的
这个就是可以将我们print函数输出的数据进行改变
我们想print输出啥这个就能改成啥,主要是以return进行返回来实现这个操作的
这个只能设置print输出的内容
如果我们需要改变交互模式输出的话,我们是可以通过这种魔法方法的
repr(self):设置直接输出对象名时的显示内容
class Test:
#构造函数
def __init__(self,name):
self.name=name#这个self就是指向的对象
print("这是一个初始化方法")
#析构函数--对对象进行销毁的操作
def __del__(self):
print(f'{self.name}进行销毁')
#设置print输出对象名时显示的内容
def __str__(self):
return "这是一个魔法方法__str__设置的"
#__repr__(self):设置直接输出对象名时的显示内容
def __repr__(self):
return '这是__repr__设置显示的内容'
t1=Test("张三")
print(t1)
#这是一个魔法方法__str__设置的
'''
交互模式:
print(t1)
这是一个魔法方法__str__设置的
t1
这是__repr__设置显示的内容
'''
这个魔法方法可以直接将交互结果进行改变的
这个输出的话感觉用的很少
回顾:
定义实例方法:def 函数名(self)
调用实例方法:self.方法名或对象名.方法名
对象关系方法--isinstance(对象,类)
#isinstance(对象,类)
#判断对象是不是后面的类实例出的对象
print(isinstance(t1,Test))#这里我们前面创建了,只不过这里没有复制过来
#True
#就是判断我们第一个参数是不是通过第二个参数(类)实例化出来的
#这个就是进行类型的判断
print(isinstance(1,int))
#True
print(isinstance(1.5,int))
#False
判断这个对象是不是这个类实例话出来的
还能判断1是不是整型
返回值都是bool值
单继承
举个例子:就是富二代从他爸那里继承了财产,这个就叫继承,富二代什么都不做
继承发生在两个类之间的
继承的关系是双方是父类和子类
继承可以使子类具有父类的所有属性和方法
class Father:#父亲类
def money(self):
print('100万')
#单继承:class子类名(父类名)
class Son(Father):#子类
#重写:在子类中定义一个与父类方法同名的方法就是重写,那么这个子类就不会去执行父亲类了
def money(self):
print('1000万')
#用儿子类创建出来的对象进行父亲类中实例方法的调用
s=Son()
s.money()
#100万
#子类可以通过继承父类,获取父类中的方法、属性
单继承:class子类名(父类名)
重写的操作:如果现在我们不需要使用父亲类中的方法的话,那么我们在子类中再定义一个同名的方法就能进行覆盖的操作
我们可以使用_ mro****_进行搜索顺序的查询
#__mro__:查询搜索顺序
print(Son.__mro__)
#(<class '__main__.Son'>, <class '__main__.Father'>, <class 'object'>)
#我们在执行这个money的时候我们先看自己类有没有这个方法
#如果自己类有这个方法的话就调用自己的,如果没有的话就看看父亲类有没有
#如果父亲类没有的话就去基类里面找,但是基类的话可能没有,那么就会进行报错的操作
#自己有就用自己的,自己没有就用父亲的
(, , )
从自己开始搜索,如果自己没有就用父亲的,父亲没有的话就会报错
但是我们进行重写操作之后又想用父亲类里面的,该怎么做呢?
#但是我们进行重写操作之后又想用父亲类里面的,该怎么做呢?
#我们可以进行扩展:
#扩展可以执行父类中的同名方法
#方法一:父类名().方法名(self)
class Father:
def money(self):
print('100万')
class Son(Father):
def money(self):
print('1000万')
#扩展可以执行父类中的同名方法
#方法一:父类名.方法名(self)
Father.money(self)
#方法二:super().方法名()#调用下一个类中的方法
#就是我们的搜索顺序是子类到父类到基类
#那么调用下一个类中的方法就是去父类里面找
super().money()
s=Son()
s.money()
#1000万
#100万
#通过方法一:我们也能调用父亲类里面的money方法了
#100万--第三种方法
方法一:父类名.方法名(self)
方法二:super().方法名()#调用下一个类中的方法
对于方法二来说的话,我们的搜索顺序是子类→父类→基类
那么子类的下一个类中的方法就是父类中的方法
通过这两种方法我们也能去调用父类中的方法了
多继承
一个子类同时继承多个父类
class 子类(父类1,父类2,......)
#一个子类同时继承多个父类就是多继承
class Father:
def money(self):
print('100')
class Mother:
def host(self):
print("三室一厅")
class Son(Father,Mother):
pass
s=Son()
s.money()
s.host()
#100
#三室一厅
子类啥都不干就能继承父亲和母亲的
下面的代码介绍了多父类的搜索顺序
class Father:
def money(self):
print('100')
class Mother:
def money(self):
print('1000')
def host(self):
print("三室一厅")
class Son(Father,Mother):
#重写操作
def money(self):
print("10")
#扩展
#扩展一:super().方法名()---这个扩展的是下一个类里面的对应的方法,就是Father里面的方法
super().money()#子类后面的类中第一个有money的类
#扩展二 父类名.方法()
Father.money(self)
Mother.money(self)
s=Son()
s.money()
s.host()
#现在父亲类和母亲类都有money
#那么儿子调用money的时候是调用谁的呢?
#100
#三室一厅
#为什么是这样的呢?
#我们可以试试看看搜索顺序是如何的
print(Son.__mro__)
#(<class '__main__.Son'>, <class '__main__.Father'>, <class '__main__.Mother'>, <class 'object'>)
#先是子类,再是父类,再是母类,最后是基类
#这个顺序依照的就是我们在子类继承多类的时候写在括号内的顺序的
#class Son(Father,Mother):
#如果我们先写的是Mother的话,那么这个搜索顺序肯定是Mother排第二个
搜索的顺序取决于这个我们在继承操作时在括号中写的顺序
如果是mother写在前面那就子类过后就搜索mother中是否存在对应的方法
这个上面的代码还介绍了如何进行扩展操作的,访问父类和子类中的money方法
两种方法
建议使用这个第二种方法: 父类名.方法()
这种直接就指定了拓展哪个类里面的哪个方法