Python中的__getattr__和__getattribute__

Python
Author

metseq

Published

November 9, 2022

1 __getattr__

如果在类中实现了_getattr__方法,那么当使用对象.属性的时候,如果属性不在对象里,则会调用__getattr__方法。

class Point():
    def __init__(self, x, y):
        self.x = x
        self.y = y
p = Point(3, 4)
print(p.x, p.y)
print(p.z)
3 4
AttributeError: 'Point' object has no attribute 'z'

因为Point没有z这个属性,所以报错了。

下面这个类实现了__getattr__方法,看看会怎么样

class Point():
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __getattr__(self, name):
        print('exec __getattr__ 😀')
        print(f'name: {name}')
        return 42
p = Point(3, 4)
p.z
exec __getattr__ 😀
name: z
42
Tip

__getattr__方法接受两个参数,self不用说,name就是属性名称,在上面的例子就是z

2 __getattribute__

如果在类中实现了__getattribute__方法,那么当使用对象.属性的时候,都会调用__getattr__方法。

Tip

注意_getattr__是当属性不在对象里的时候在调用

class Point():
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __getattribute__(self, name):
        print('exec __getattr__ 😀')
        print(f'name: {name}')
        return 42
p = Point(3, 4)
p.x, p.y, p.z
exec __getattr__ 😀
name: x
exec __getattr__ 😀
name: y
exec __getattr__ 😀
name: z
(42, 42, 42)

p.x, p.yp.z都调用了__getattribute__方法