python-魔法方法
魔法方法
python中一切皆对象,因为python是面向对象的编程语言。python给类和对象提供了大量的内置方法,这些内置方法也称魔法方法。这些魔法方法总是在某种条件下自动触发执行,就像魔法一样。
#1 __str__()
__str__是当对象被访问打印时触发执行,它必须有一个字符串类型的返回值
#2 __del__()
__del__是当对象被回收时触发执行(程序结束、对象引用计数为零称为垃圾时)
#3 __new__()
__new__是当类被调用实例化对象时第一个被触发的函数,用来实例化并返回一个空对象
#4 __init__()
__init__是当接收__new__返回的空对象后触发执行,完成空对象的初始化操作,没有返回值
#5 __call__()
__call__是当对象加括号被调用时触发执行;类中的__call__在对象被调用时触发;元类中的__call__在类实例化时被触发
#6 __enter__();__exit__()
with上下文管理必须的__enter__()在进入时触发执行;__exit()__在退出时触发执行
#7 item系列:__getitem__(), __setitem__(), __delitem__()
[]拦截方法
#8 attr系列:__getattr__(), __setattr__(), __delattr__()
.拦截方法;当对象属性不存在会执行__getattr__
#9 __getattribute__()
无论对象点属性方法是否存在都会触发该方法执行,切记不能在该方法内调用对象任何的属性,即使采用反射的方式
当__getattribute__与__getattr__共存时则仅执行__getattribute__
#10 __eq__()
__eq__()是两个对象坐比较时,触发执行的方法
手写上下文管理with
class MyWith():
def __init__(self, name):
self.name = name
def __enter__(self):
return self # 返回的数据赋值给p
def __exit__(self, exc_type, exc_val, exc_tb):
pass
with MyWith('jack') as p:
print(p.name)
item系列
class Person(object):
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('jack')
p['name'] = 'mack' # 需要__setitem__才可以
print(p['name']) # 需要__getitem__才可以
print(p.__dict__)
attr系列
###################################### .拦截
class MyDict(dict):
def __getattr__(self, item):
return self.get(item)
def __setattr__(self, key, value):
if not isinstance(value, str):
raise ValueError('值必须是字符串类型')
self[key] = value
d = MyDict({'name':'jack'})
print(d.name) #如果没有__getattr__()则报错
d.age = 123
print(d)
####################################### __getattr__(), __setattr__(), __delattr__()
class Person(object):
def __init__(self, name):
self.name = name
def __getattr__(self, item):
print('调用不存在的属性会触发我')
# print(p.age)
return self.__dict__.get(item)
def __setattr__(self, key, value):
print('设置修改对象属性时触发我')
self.__dict__[key] = value
def __delattr__(self, item):
print('删除对象属性时触发我')
self.__dict__.pop(item)
p = Person('jack') # 触发__setattr__
p.name = 'mack' # 触发__setattr__
print(p.age) # 触发__getattr__
p.age = 18 # 触发__setattr__
del p.age # __delattr__