您的所有属性都是 的原因None,即使是不存在的属性,例如favorite,是这样的:
def __getattribute__(self, item):
print('__getattribute__() be called. Item is: ', item)
您正在object.__getattribute__使用始终返回的方法覆盖普通代码None。如果你想让它打印一些东西并做正常的事情,你必须明确地使用super——就像你在初始化器中所做的那样:
def __getattribute__(self, item):
print('__getattribute__() be called. Item is: ', item)
return super().__getattribute__(item)
如果你解决了这个问题,现在可以查找存在的属性,但不存在的属性仍然会返回None而不是引发AttributeError. 为什么?
def __getattr__(self, item):
print('__getattr__() be called. Item is: ', item)
正常object.__getattribute__(您现在正确调用)在对象的__dict__、其类和所有其类的祖先中查找属性(与我将在此处忽略的描述符相关的一些额外复杂性),并且然后,如果什么都没有找到(或者找到了一些东西但获取它会引发AttributeError),它会调用类的__getattr__. 而你提供一个__getattr__返回None。
在这里,您再次想委托给超类:
def __getattr__(self, item):
print('__getattr__() be called. Item is: ', item)
return super().__getattr__(item)
除了没有. _ __getattr__所以,你会得到一个AttributeError,但这将是关于一个super没有 a __getattr__,而不是关于一个Cat没有 a favorite。
如果你知道你的一个基类想要__getattr__为你提供一个委托super给它。但是,如果您知道没有人这样做:
def __getattr__(self, item):
print('__getattr__() be called. Item is: ', item)
raise AttributeError(item)
如果你不知道(因为,比如说,你的类被设计成与其他人的类层次结构混合使用),你可能想要这样的东西:
def __getattr__(self, item):
print('__getattr__() be called. Item is: ', item)
try:
ga = super().__getattr__
except AttributeError:
pass
else:
return ga(item)
raise AttributeError(item)
如果你修复了这两个,现在你会得到AttributeError你设置的属性。为什么?
def __setattr__(self, key, value):
print('__setattr__() be called. key and Value is: ', key, value)
同样的问题。在这里,您可能希望显式设置属性,如下所示:
def __setattr__(self, key, value):
print('__setattr__() be called. key and Value is: ', key, value)
super().__getattribute__('__dict__')[key] = value
……或者您可能只想再次委托:
def __setattr__(self, key, value):
print('__setattr__() be called. key and Value is: ', key, value)
super().__setattr__(key, value)