> 魔术方法也和普通方法一样都是类中定义的成员方法
> 魔术方法不需要去手动调用的,魔术方法会在某种情况下,自动触发(自动执行)
> 魔术方法还有一个比较特殊的地方:就是多数的魔术方法 前后都有两个连续的下划线
> 魔术方法不是我们自己定义的,而是系统定义好的,我们来使用
__init__初始化方法
__init__ 初始化方法
触发机制:在通过类实例化对象后,自动触发的一个方法
作用: 可以在对象实例化后完成对象的初始化(属性的赋值,方法的调用,打开或创建一些资源)
参数: 一个self,接受当前对象,其它参数根据需求进行定义即可
返回值: 无
注意事项:无
应用场景: 文件的打开,数据的获取,干活前的一些准备功能。
# __init__初始化方法
class Person():
name = None
sex = None
age = None
def __init__(self,a,b,c):
# 完成对象属性的初始化
self.name = a
self.sex = b
self.age = c
self.say()
def say(self):
print(f'hello,world!我叫{self.name},{self.sex},今年{self.age}')
# 实例化对象
Amanda = Person('Amanda',3,'女')
print(Amanda.name)
输出结果:
hello,world!我叫Amanda,3,今年女
Amanda
__del__析构方法
__del__ 析构方法
触发机制:析构方法会在对象被销毁时自动触发
作用:关闭或释放对象创建时打开或创建的一些资源
参数: 一个self,接受当前的对象
返回值:无
注意事项: 无
注意:是对象被销毁时触发了析构方法,而不是析构方法销毁了对象
对象会在哪些情况下被销毁?
1。 当程序执行完毕,内存中所有的资源都会被销毁释放
2。 使用 del 删除时
3。 对象没有被引用时,会自动销毁,
记住,没有变量去引用的时候就会被销毁,
比如下例中的:writeLog()、Cart('宝马'),
这样写是没有变量引用的,所以初始化之后会直接被销毁
__ new__ 构造方法
__new__ 构造方法 ****
触发机制:实例化对象时自动触发(在__init__之前触发)
作用: 管理控制对象创建的过程
参数: 一个cls 接收当前类,其它参数根据初始化方法的参数进行决定
返回值: 必须返回object.__new__(cls)进行对象的创建,如果没有返回值,则实例化对象的结果为None
注意事项:
__new__方法的参数和__init__方法的参数要保持一致,除了第一个参数
必须返回object.__new__(cls)进行对象的创建,如果没有返回值,则实例化对象的结果为None
应用场景:设计模式中的单例设计模式
__ call __
__call__
触发机制: 把对象当作函数直接调用时自动触发
作用: 一般用于归纳类或对象的操作步骤,方便调用
参数: 一个self接收当前对象,其它参数根据调用需求缺点
返回值: 可有可无
__ len__
__len__
触发机制: 当使用len函数去检测当前对象的时候自动触发
作用: 可以使用len函数检测当前对象中某个数据的信息
参数: 一个self 接收当前对象
返回值: 必须有,并且必须是一个整型
注意事项:len要获取什么属性的值,就在返回值中返回哪个属性的长度即可
__ str__
__str__
触发机制: 当使用str或者print函数对对象进行操作时自动触发
作用: 代码对象进行字符串的返回,可以自定义打印的信息
参数: 一个self,接收当前对象
返回值: 必须有,而去必须是字符串类型的值
__ repr__
__repr__
触发机制:在使用repr方法对当前对象进行转换时自动触发
作用: 可以设置repr函数操作对象的结果
参数: 一个self,接收当前对象
返回值: 必须有,而去必须是字符串类型的值
注意:正常情况下,如果没有__str__这个魔术方法,__repr__方法就会代替__str__魔术方法
__ bool__
__bool__
触发机制: 当前使用bool函数转换当前对象时,自动触发.默认情况下,对象会转为True
作用: 可以代替对象进行bool类型的转换,可以转换任何数据
参数 : 一个self 接收对象
返回值: 必须是一个布尔类型的返回值
# 定义一个人类
class Person():
# 构造方法
def __new__(cls, *args):
print('触发了构造方法')
# 如果在该方法中没有返回如下格式,则无法创建对象
return object.__new__(cls)
# 初始化方法
def __init__(self,name,age,sex):
print('触发了初始化方法')
self.name = name
self.age = age
self.sex = sex
def __call__(self, *args, **kwargs):
print('你把对象当成了函数进行调用')
# 析构方法
def __del__(self):
print('触发了析构方法')
# 实例化对象
am = Person('Amanda',23,'girl')
# print(am)
am()
class Demo():
listurl = []
# 可以代替对象使用len函数,并返回一个指定的整型
def __len__(self):
return len(self.listurl)
# 可以代替对象进行str或者print的字符串信息返回
def __str__(self):
return '这是当前脚本中的一个_对象 str'
def __repr__(self):
return '这个是一个对象'
def __bool__(self):
return bool(self.listurl)
日志封装:
'''
定义一个类,完成一个日志的记录
调用这个对象的时候,传递一个日志信息
这个对象会创建一个文件,开始写入,并在最后关闭这个文件
'''
import time
class writeLog():
fileurl = './' # 默认路径为当前目录
filename = time.strftime('%Y-%m-%d ')+'.log'
fileobj = None
def __init__(self):
print('文件已打开')
self.fileobj = open(self.fileurl+self.filename,'a+',encoding='utf-8')
def log(self,s):
data = time.strftime('%Y-%m-%d %H:%M:%S')
w = data+' '+s+'\n' # 加上空格和换行符是为了美观
self.fileobj.write(w)
print('over')
def __del__(self):
print('文件已关闭')
self.fileobj.close()
m = input('请输入日志内容\n')
mylog = writeLog()
mylog.log(m)
输出结果试例:
成员相关魔术函数:
1.__getattribute__ 优先级最高
触发机制:当访问对象成员时,自动触发,无论当前成员是否存在
作用: 可以在获取对象成员时,对数据进行一些处理
参数: 一个self接收对象,一个item接收当前访问的成员名称
返回值: 可有可无,返回的值就是访问的结果
注意事项:在当前的魔术方法中,禁止对当前对象的成员进行访问,会触发递归。
如果想要在当前魔术方法中访问对象的成员必须使用 object 来进行访问
格式: object.__getattribute__(self,item)
2.__getattr__
触发机制: 当访问对象中不存在的成员时,自动触发
作用: 防止访问不存在的成员时报错,也可以为不存在的成员进行赋值操作
参数: 一个self接收当前对象,一个item接收当前访问的成员名称
返回值: 可有可无
注意事项: 当存在 __getattribute__ 方法时,会去执行 __getattribute__ 方法
也要注意,不要在当前的方法中再次去访问这个不存在的成员,会触发递归操作
3.__setattr__
触发机制: 当给对象的成员进行赋值操作时会自动触发(包括添加,修改)
作用: 可以限制或管理对象成员的添加和修改操作
参数: 1。self 接收当前对象 2。key 设置的成员名 3。val 设置的成员值
返回值: 无
注意事项:在当前的魔术方法中禁止给当前对象的成员直接进行赋值操作,会触发递归操作
如果想要给当前对象的成员进行赋值,需要借助 object
格式: object.__setattr__(self,key,value)
4.__delattr__
触发机制: 当删除对象成员时自动触发
作用: 可以去限制对象成员的删除,还可以删除不存在成员时防止报错
参数:1,self 接收当前对象 2。item 删除的成员名称
返回值: 无
注意事项: 在当前魔术方法中禁止直接删除对象的成员,会触发递归操作。
如果想要删除当前对象的成员,那么需要借助 object
格式: object.__delattr__(self,item)
访问成员的顺序!!!
1. 调用 `__getattribute__ `魔术方法
2. 调用数据描述符【后面会讲】
3. 调用当前对象的成员
4. 调用当前类的成员
5. 调用非数据描述符【后面会讲】
6. 调用父类的成员
7. 调用`__getattr__`魔术方法
> 以上步骤时调用某个成员时的顺序,前面的能够调用成功,后面则不在执行