我在行if hasattr(self, '_ubuffer')
中获得了最大递归深度错误。谁能看到我在这里做错了什么?该函数的整个代码是:
def __getattr__(self, name):
if hasattr(self, '_ubuffer'):
buffer = object.__getattribute__(self,'_ubuffer')
if name in buffer.dtype.names:
return buffer.data[name]
return object.__getattribute__(self,name)
答案 0 :(得分:5)
hasattr
调用__getattr__
会导致递归。 From the docs:
hasattr(object, name)
参数是一个对象和一个字符串。如果字符串是对象属性之一的名称,则结果为True,否则返回False。 (这是通过调用getattr(object,name)并查看是否引发异常来实现的。) [我的重点]
解决此问题的一种方法可能是用if hasattr(self, '_ubuffer')
替换if '_ubuffer' in self.__dict__
。
答案 1 :(得分:1)
@maciej-gol 提出的方法相当不错,但是它没有处理超类没有定义自定义 __getattr__
的常见情况(至少对于 Python3)。为避免此类问题,最好先使用始终定义的 __getattribute__
检查,如果失败则回退到 _getattr_
。
如果您事先不知道基类是否实现了自定义 __getattr__
方法,我建议您这样做:
def __getattr__(self, name):
try:
buffer = self.__getattribute__('_ubuffer')
except AttributeError:
try:
buffer = super().__getattr__('_ubuffer')
except AttributeError:
raise AttributeError('Attribute {} not found.'.format(name))
if name in buffer.dtype.names:
return buffer.data[name]
raise AttributeError('Attribute {} not found.'.format(name))
但在大多数情况下,只需使用 __getattribute__
就足够了:
def __getattr__(self, name):
try:
buffer = self.__getattribute__('_ubuffer')
if name in buffer.dtype.names:
return buffer.data[name]
raise AttributeError
except AttributeError:
raise AttributeError('Attribute {} not found.'.format(name))
答案 2 :(得分:0)
您可以使用超类实现进行常规属性访问:
def __getattr__(self, name):
try:
buffer = super(MyClass, self).__getattr__('_ubuffer')
except AttributeError:
raise AttributeError('Attribute {} not found.'.format(name))
if name in buffer.dtype.names:
return buffer.data[name]
else:
raise AttributeError('Attribute {} not found.'.format(name))