__getattr__和__getattribute__的区别

getattr(self, item)定义当用户试图获取一个不存在的属性的行为
getattribute(self, item)定义该类的属性被访问时的行为

因为,计算机肯定先访问存在的属性,如果没有,再访问不存在的属性,即先访问getattribute(self, item),再访问getattr(self, item)

举例1:

class Demo:
    def __getattr__(self, item):
        return "该属性不存在"

demo=Demo()
print (demo.x)

则输出:该属性不存在

举例2:

class C:
    def __getattr__(self, name):
        print(1)

    def __getattribute__(self, name):
        print(2)

    def __setattr__(self, name, value):
        print(3)

    def __delattr__(self, name):
        print(4)

c = C()
c.x = 1
# 位置一,请问这里会显示什么?
print(c.x)
# 位置二,请问这里会显示什么?

位置一会显示3,因为c.x=1是赋值操作,所以会访问setattr()魔法方法:位置二回显示2和None,因为x是属于实例对象c的属性,所以c.x是访问一个存在的属性,因为会访问getattribute()魔法方法,但我们重写了这个方法,使得它不能按正常的逻辑返回属性值,而是打印一个2代替,由于我们没有写返回值,所以紧接着返回None,并被print()打印出来。

举例3:

class C:
    def __getattr__(self, name):
        print(1)
        return super().__getattr__(name)

    def __getattribute__(self, name):
        print(2)
        return super().__getattribute__(name)

    def __setattr__(self, name, value):
        print(3)
        super().__setattr__(name, value)

    def __delattr__(self, name):
        print(4)
        super().__delattr__(name)

c = C()
c.x

显示结果为:

Traceback (most recent call last):
2
  File "E:/Python Program/test.py", line 128, in <module>
1
    c.x
  File "E:/Python Program/test.py", line 113, in __getattr__
    return super().__getattr__(name)
AttributeError: 'super' object has no attribute '__getattr__'

原因:
首先c.x会先调用getattribute()魔法方法,打印2;然后调用super().getattribute(),找不到属性名x,因此会紧接着调用getattr()魔法方法,于是打印1,然后调用super().getattr()。但是Python会告诉你AttrError,super对象木有getattr()!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值