__getattr__,__setattr__,__delattr__,__getattribute__,记录

马上上个概念,前面的__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

因为要不然,你输入没有的属性也不会报错,感觉不是太好。

猜你喜欢

转载自www.cnblogs.com/sidianok/p/11795720.html