python getattribute方法_python魔法方法 _getattr_ 和 __getattribute__

python的easyDict库,是一个属性调用友好库

python中对象属性的获取链

在使用obj.value时,python内部执行顺序如下:

obj.value等价于getattr(obj,'value'),会调用基类object  Python默认的__getattribute__方法,该方法逻辑如下:

最开始,python会使用obj.__dict__[value]的方法查找,也就是查找对象内置字典的key值

如果上述方法查找不到,会使用type(obj).__dict__[value]来查找,也就会查找obj类的属性

如果上述方法查找不到,python会用mro的查找方法遍历type(obj)的基类,在其基类中查找类属性,知道找到位置

如果还是找不到,__getattribute__在抛出AttributeError前会调用__getattr__方法

内置方法__getattr__

如果我们在类中定义了__getattr__方法,当使用正常的逻辑访问属性(如:obj.a)而找不到该属性时,就会调用这个__getattr__方法。

内置方法__getattribute__

之前所说的查找方式为默认的Python的调用逻辑,当在类内定义了__getattribute__方法,就会打破原有属性查找方式,在obj.value查找属性时,会无条件条用__getattribute__方法。

使用归纳:

1.__getattribute__方法优先级比__getattr__高

2.只有在__getattribute__方法中找不到对应的属性时,才会调用__getattr__

3.如果是对不存在的属性做处理,尽量把逻辑写在__getattr__方法中

4.如果非得重写__getattribute__方法,需要注意两点:第一是避免.操作带来的死循环;第二是不要遗忘父类的__getattribute__方法在子类中起的作用

实例一:

class A(object):

def __init__(self):

self.name = "Bob"

self.age = 18

self.gender = "male"

if __name__ == "__main__":

a = A()

print(a.name)

print(a.age)

print(a.gender)

输出结果:

Bob

18

male

实例二:存在__getattribute__时,调用已存在的属性,直接调用__getattribute__

# -*- coding:utf-8 -*-

# coding=utf-8

class A(object):

def __init__(self):

self.name = "Bob"

self.age = 18

self.gender = "male"

def __getattribute__(self, attr): # 拦截age属性

if attr == "age":

return "问年龄是不礼貌的行为" # 非age属性执行默认操作

else:

return object.__getattribute__(self, attr)

if __name__ == "__main__":

a = A()

print(a.age)

print(a.name)

print(a.gender)

输出结果:

问年龄是不礼貌的行为

Bob

male

实例三:属性不存时,存在__getattr__,则调用__getattr__

# -*- coding:utf-8 -*-

# coding=utf-8

class A(object):

def __init__(self):

self.name = "Bob"

self.age = 18

self.gender = "male"

def __getattr__(self, attr):

return eval("self."+attr.lower()) #即:再次去执行__getattribute__方法

if __name__ == "__main__":

a = A()

print("a.name -> {}".format(a.name))

print("a.NAME -> {}".format(a.NAME))

print("a.Name -> {}".format(a.Name))

print("a.NaME -> {}".format(a.NaME))

输出结果:

a.name ->Bob

a.NAME ->Bob

a.Name ->Bob

a.NaME ->Bob

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值