OOP中的常用魔法方法
前言:魔法方法之所以叫做是魔法方法就是应为它们不需要人为的调用,而是在特定时刻会自动触发,魔法方法的方法名都有一个特点——前后都被双下划线包裹,因此又有人称之为双下方法
操作类
-
__init__
:构造函数,在类实例化时触发,好比直接生成了一个打扮时髦的美女 -
__new__
:该函数比较特殊,它在__init__
函数之前触发,会生成一个空的对象,与__init__
的区别就是它是生成一个没穿衣服的美女 -
__call__
:在对象加括号调用时触发 -
__str__
:对象被打印时触发,会讲该方法的返回值作为打印结果显示 -
__del__
:对象回收的时候触发
属性操作相关
点拦截方法
__getattr__
:对象.属性时触发__setattr__
:对象.属性赋值时触发
[]拦截方法
__getitem__
:对象[属性]时触发__setitem__
:对象[属性]赋值时触发
点拦截方法与[]拦截方法示例
class Person:
def __init__(self,name):
self.name=name
def __setitem__(self, key, value):
setattr(self,key,value) #反射
def __getitem__(self, item):
return getattr(self,item) # 反射取值
p=Person('daker')
p.name='pp' # 重写__setattr__魔法方法
p['name']=10 # 重写__setitem__魔法方法
print(p.name) # 重写__getattr__魔法方法
print(p['name'])# 重写__getitem__魔法方法
dic={'name':'daker','age':23}
class Mydic(dict):
def __init__(self, name, age):
self.name = name
self.age = age
def __setattr__(self, key, value):
print("对象点属性赋值,会触发我")
self[key]=value
def __getattr__(self, item):
print("对象点属性取值,会触发我")
return self[item] # 不要加引号
mydic=Mydic(**dic)
print(mydic['name'])
print(mydic.name)
mydic.name=99
print(mydic.name)
with上下文管理器
__enter__
和__exit__
示例
class Person:
def __enter__(self):
print("我在with管理的时候,会触发")
print('进入with语句块时执行此方法,此方法如果有返回值会赋值给as声明的变量')
return 'oo'
def __exit__(self, exc_type, exc_val, exc_tb):
print('退出with代码块时执行此方法')
print('1', exc_type)
print('2', exc_val)
print('3', exc_tb)
with Person() as p: # 这句话执行,会触发类的__enter__
print(p)
__eq__
:当对象执行时会触发,会将后面的对象作为参数传入
示例
class A:
def __init__(self,x,y):
self.x = x
self.y = y
def __eq__(self,obj):
# 打印出比较的第二个对象的x值
print(obj.x)
if self.x +self.y == obj.x+obj.y:
return True
else:
return False
a=A(1,2)
b=A(99,3)
print(a==b) # 当对象执行==时,会触发__eq__的执行,并且把b传进去,就是object
# ==后只要是对象,就可以传进去,就是object