马上上个概念,前面的__getitem__,__setitem__,__delitem__回顾下
这个是用在对象[],好比list[0]=1 ,dict[‘ok‘] = 12,基本是容器类数据的增删改查
今天的魔法方法主要是属性与方法的调用,好比xx.live()或者xx.number
在进行属性增删改查的时候,标题的4个魔方方法就开始各显神通了。
在Python的实例对象里面感觉就没有方法了,任何的方法可以理解为能被调用的属性,我在看书的时候好像对于对象的介绍很少提起方法的(除了魔法方法这个名字,其实它也是一个属性)。
概念来了:
__getattriburte__(self,name):在属性被访问时自动调用,(只适合与新式类)
__getattr__(self,name):在属性被访问,而对象没有这个属性被调用。(这个记住是找不到到这里。)
__setattr__(self,name, value):试图给属性复制是被调用。
__delattr__(self, name):试图删除属性时自动调用。
上代码:
class Rectange:
def __init__(self):
self.width = 0
self.height = 0
def __getattribute__(self, name):
print(f‘{name}属性被调用‘)
return super(Rectange, self).__getattribute__(name)
def __setattr__(self, name, value):
print(‘setattr被调用‘)
if name == ‘size‘:
self.width, self.height = value
else:
# super(Rectange, self).__setattr__(name,value) # 调用父类赋值,不会激活__getattribute_
# self.name = ‘value‘ # 会继续调用__setattr__然后就是死循环
self.__dict__[name] = value
def __getattr__(self, name):
if name == ‘size‘:
return self.width, self.height
else:
print(f‘{name}的属性没找到‘)
raise AttributeError
# super(Rectange, self).__getattr__(name) # 结果测试父类没有__getattr__方法,所以不能调用父类
def __delattr__(self, name):
print(f‘{name}的属性被删除了‘)
super(Rectange, self).__delattr__(name)
r = Rectange()
‘‘‘
【实例化的时候,属性被复制,输出】
setattr被调用
__dict__属性被调用
setattr被调用
__dict__属性被调用
‘‘‘
r.size = 3,5
‘‘‘
【进入__setattr__输出print(‘setattr被调用‘),后面两个属性通过__dict__赋值,所以输出了两次get与set被调用,共4次】
setattr被调用
setattr被调用
__dict__属性被调用
setattr被调用
__dict__属性被调用
‘‘‘
r.hh # 输入一个没有的属性
‘‘‘
hh属性被调用
hh的属性没找到
Traceback (most recent call last):
File "/Users/shijianzhong/Desktop/yunzuan_buy/1.py", line 35, in <module>
r.hh
File "/Users/shijianzhong/Desktop/yunzuan_buy/1.py", line 24, in __getattr__
raise AttributeError # 第一种方法
AttributeError
‘‘‘
del r.width
print(r.width)
‘‘‘
width的属性被删除了
width属性被调用
width的属性没找到
Traceback (most recent call last):
File "/Users/shijianzhong/Desktop/yunzuan_buy/1.py", line 36, in <module>
print(r.width)
File "/Users/shijianzhong/Desktop/yunzuan_buy/1.py", line 24, in __getattr__
raise AttributeError # 第一种方法
AttributeError
‘‘‘
通过上面的代码可以看到,除了__getattr__意外另外的都可以继承父类,直接调用父类更加安全。
在使用__getattr__的时候,建议还是加上raise AttributeError
因为要不然,你输入没有的属性也不会报错,感觉不是太好。
__getattr__,__setattr__,__delattr__,__getattribute__,记录
原文:https://www.cnblogs.com/sidianok/p/11795720.html