object.__getattr__(self, name) 当默认属性访问因AttributeError而失败时,调用此方法。(因name不是实例属性或类树中属于self的属性,__getattribute ()将引发AttributeError或者get __()获取name属性时引发AttributeError)。 此方法应返回(计算)属性值或引发AttributeError异常。

请注意,当调用不存在的属性时,Python会试图调用getattr()来获取属性。如果是已经存在的属性,那不调用getattr(),直接返回属性的值。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Dog:
    def __getattr__(self, name):
        if name == 'color':
            return 'black'
        else:
            raise AttributeError

#实例d
d = Dog()

#实例d没有名为color的属性,因此在提供计算值时将调用__getattr__(self, name) 。
print(d.color)  #输出'black'

#实例d添加属性color
d.color = 'gray'

#d.color不调用__getattr__() 方法,因为d.color已在该实例中定义。
print(d.color)  #输出'gray'

执行以上程序会输出如下结果:

1
2
black
gray

object.__getattribute__(self, name) 无条件调用以实现类的实例的属性访问。 如果该类还定义了__getattr (),则除非getattribute ()显式调用它或引发AttributeError,否则不会调用getattr __()。 此方法应返回(计算)属性值或引发AttributeError异常。

为了避免此方法中的无限递归,其实现应始终调用具有相同名称的父类方法来访问其所需的任何属性,例如,object.__ getattribute __(self,name)。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Dog:
    def __getattribute__(self, name):
        if name == 'color':
            return 'black'
        else:
            raise AttributeError

#实例d
d = Dog()

#访问d的color属性。因定义了__getattribute__实例方法,访问属性时,无条件调用此方法
print(d.color)  #输出'black'

#实例d添加属性color
d.color = 'gray'

#即使d有了color属性,也还是会调用__getattribute__。
print(d.color)  #输出'black'

执行以上程序会输出如下结果:

1
2
black
black

注意,所有属性和方法的访问操作都是通过getattribute()完成(特殊方法名称除外,因为那样将会导致讨厌的无限循环)。

1
2
3
4
5
6
7
8
9
class Dog:
    def __getattribute__(self, name):
        raise AttributeError

    def swim(self):
        pass

d = Dog()
d.swim()   #报错,因为会先执行__getattribute__方法,抛出AttributeError异常

执行以上程序会输出如下结果:

1
2
3
4
5
6
Traceback (most recent call last):
  File "main.py", line 9, in <module>
    d.swim()
  File "main.py", line 3, in __getattribute__
    raise AttributeError
AttributeError

如果有特殊的要求,可以重载getattribute方法,下面实现一个不能使用append方法的list。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class ListNotAppend(list):
    def __getattribute__(self,name):
        if name == 'append':
            raise AttributeError
        return list.__getattribute__(self, name)

a = ListNotAppend()

print(type(a)) # 输出<class '__Main__.ListNotAppend'>

a.append() # 报错,抛出定义好的异常
<class '__main__.ListNotAppend'>                       Traceback (most recent call last):                       File "/home/main.py", line 11, in <module>               a.append()
  File "/home/main.py", line 4, in __getattribute__        raise AttributeError                             AttributeError

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Dog:
    def __getattribute__(self, name):
        if name == 'color':
            return 'black'
        else:
            return "unkown"

    def __getattr__(self, name):
        if name == 'age':
            return 10
        else:
        raise AttributeError
#实例d
d = Dog()

#访问d的color属性。因定义了__getattribute__实例方法,访问属性时,无条件调用此方法
print(d.color)  #输出'black'

#虽然有__getattr__方法,也不会调用。还是会调用__getattribute__
print(d.age)  #输出'unkown'

#访问不存在的属性还是会调用__getattribute__
print(d.weight)  #输出'unkown'

执行以上程序会输出如下结果:

1
2
3
black
unkown
unkown

转载请注明本网址。