python笔记61 - __getattr__ 属性查找学习与使用

前言

object 类里面有个 __getattribute__ 方法,作用是类实例化调用属性和方法的时候都会调用一次,返回该类的属性。
如果调用的属性没有,会抛出 AttributeError 异常。如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__)失败, 那么会调用到类的__getattr__方法。

__getattribute__方法

A类在调用自身属性的时候,是不会触发__getattribute__()方法。
只有在调用A()实例属性或方法的时候,才会触发__getattribute__()方法

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class A(object):

count = 0

def __init__(self):
self.name = "yoyo"
self.age = 18

def start(self):
print("start1111111")

def __getattribute__(self, item):
"""属性拦截器"""
print("调用了A类的属性:", item)
return object.__getattribute__(self, item)

a = A()
# A()实例对象属性会调用__getattribute__
print(a.count)
print(a.age)
print(a.name)
print(a.start())

如果A类属性(__dict__)没查找到,并且实例属性和方法也没找到,此时会抛出 AttributeError 异常

a = A()
print(a.weight) # 找不到属性

运行结果

调用了A类的属性: weight
Traceback (most recent call last):
File "demo/aaa.py", line 27, in <module>
print(a.weight) # 找不到属性
File "demo/aaa.py", line 18, in __getattribute__
return object.__getattribute__(self, item)
AttributeError: 'A' object has no attribute 'weight'

__getattr__方法

如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__)失败, 那么会调用到类的__getattr__方法。

# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/

class A(object):

count = 0

def __init__(self):
self.name = "yoyo"
self.age = 18

def start(self):
print("start1111111")

def __getattribute__(self, item):
"""属性拦截器"""
print("调用了A类的属性:", item)
return object.__getattribute__(self, item)

def __getattr__(self, item):
"""属性找不到会执行这个方法"""
print("找不到该属性:%s" % item)
return 'not found'

a = A()
# A()实例对象属性会调用__getattribute__
print(a.count)
print(a.age)
print(a.weight)

运行结果不会出现异常

调用了A类的属性: count
0
调用了A类的属性: age
18
调用了A类的属性: weight
找不到该属性:weight
not found

使用场景

网上有个很经典的使用示例,访问字典的key,像访问属性一样访问字典。
字典取值有2种方式,通过dict[key] 和dict.get(key)的方式取值。

a = {
"name": "yoyo",
"age": 18
}

# 字典访问
print(a["name"])
print(a.get("name"))

在其它语言里面,比如javascript里面可以把json当一个object对象,通过a.name,a.age这种点的方式就能直接取值了。
于是我们自己写一个类来实现这种方式

class ObjectDict(dict):
def __init__(self, *args, **kwargs):
super(ObjectDict, self).__init__(*args, **kwargs)

def __getattr__(self, name):
value = self[name]
if isinstance(value, dict):
value = ObjectDict(value)
return value

if __name__ == '__main__':
a = {
"name": "yoyo",
"age": 18
}
obj = ObjectDict(a)
print(obj.name)
print(obj.age)

也可以传多个值

if __name__ == '__main__':
obj = ObjectDict(a={'age': 1, 'name': 'yoyo'}, d=True)
print(obj.a)
print(obj.a.name)
print(obj.d)

dict嵌套dict也可以通过.的方式取值

if __name__ == '__main__':
obj = ObjectDict(a={'age': 1,
'name': 'yoyo',
'data': {'id': 11, 'tel': 12345678900}}, d=True)
print(obj.a)
print(obj.a.name)
print(obj.a.data)
print(obj.a.data.id)
print(obj.a.data.tel)

运行结果

{'age': 1, 'name': 'yoyo', 'data': {'id': 11, 'tel': 12345678900}}
yoyo
{'id': 11, 'tel': 12345678900}
11
12345678900

参考资料https://www.cnblogs.com/xybaby/p/6280313.html

(0)

相关推荐

  • Python获取对象信息之内置函数dir()

    对于类对象或实例对象,可以调用内置函数dir()获取其所有可以访问的属性和方法(包括从父类中继承的属性和方法)的列表.类对象与实例对象的结果是有区别的,类对象的结果不包括实例属性. 示例: #codi ...

  • 面向对象的详细解读

      面向对象的详细解读 一.基本概念 1. 面向过程 (1) 概念:以过程为中心的编程思想,就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了. (2 ...

  • 反射,双下方法

    一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...

  • python的这些特殊方法你都用过哪些?一起使用后发现有这些规律

    python的这些特殊方法你都用过哪些?一起使用后发现有这些规律

  • (12条消息) 常用的魔法方法

    魔法方法 __dict__动态绑定属性 __enter__和__exit__用来生成上下文管理器 __get__与__set__属性描述符-----给类属性添加控制条件 __getattr__与__g ...

  • Python学习——面向对象高级之反射

    反射 hasattr getattr setattr delattr 模块与函数反射 对象魔术方法 __getattr__(self, name) __setattr__(self, name) __ ...

  • python笔记61 - __getitem__ 方法学习与使用

    前言 如果在类中定义了__getitem__()方法,那么他的实例对象(假设为P)就可以这样P[key]取值. 当实例对象做P[key]运算时,就会调用类中的__getitem__()方法. __ge ...

  • 【python笔记】python java 语法,对比学习

    【python笔记】python java 语法,对比学习

  • 胡希恕伤寒论学习笔记——61

    61.下之后,复发汗,昼日烦躁不得眠,夜而安静,不呕,不渴,无表证,脉沉微,身无大热者,干姜附子汤主之. 干姜附子汤方 干姜一两 附子一枚(生用,去皮,切八片) 上二味,以水三升,煮取一升,去渣,顿服 ...

  • python笔记58-类里面的__dict__属性

    前言 python是面向对象的,对象有属性和方法,可以通过__dict__查看对象的属性 dict查看对象属性 首先弄清楚2个概念,类(A)和类的实例对象(A()), 如下代码 count 是A的类属 ...

  • python笔记59-类里面的__getattribute__属性拦截器

    前言 写了一个类,类里面写了几个方法,在调用方法的时候,希望能打印出调用了哪个方法,方便快速定位问题,于是可以用类里面的getattribute属性拦截器. python的类默认都继承了object类 ...

  • python笔记63 - __get__ 描述器(descriptor)学习

    前言 描述器定义 描述器是一个类的类属性是另一个类的实例,另一个类中实现了__set__.__delete__和__get__方法之一. 如有两个类A,B,类A中实现__set__.__delete_ ...

  • 完整版Python笔记|超级有用

    完整版Python笔记|超级有用

  • 【视频课】12小时不一样的高质量Python基础课,推荐给你学习!

    在人工智能和深度学习领域,Python语言是必须掌握的,几乎所有的开源框架都基于Python接口,数据获取与整理需要用到Python,市面上Python教程众多,但良莠不齐,本次我们联合<王的机 ...

  • Python编译器哪些好用?学习工具推荐!

    学习Python的过程中肯定少不了IDE或者代码编译器,这些工具可以帮助我们更好地加快开发效率,那么学Python用什么编译器呢?我们来看看吧. Python语言常用的编译器有两种: 第一种是Pyth ...