python函数中的最大递归深度错误

python函数中的最大递归深度错误,python,recursion,exception-handling,Python,Recursion,Exception Handling,如果hasattr(self,“\u ubuffer'),我在行中得到最大递归深度错误。有人能看出我做错了什么吗?该函数的整个代码为: def __getattr__(self, name): if hasattr(self, '_ubuffer'): buffer = object.__getattribute__(self,'_ubuffer') if name in buffer.dtype.names:

如果hasattr(self,“\u 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)

hasattr
调用将导致递归的
\uuu getattr\uuuuu

hasattr(对象,名称)
参数是一个对象和一个字符串。如果字符串是对象属性之一的名称,则结果为True,否则为False(这是通过调用getattr(对象、名称)并查看它是否引发异常来实现的。)[我的重点]


解决此问题的一种方法可能是将
if hasattr(self,'u ubuffer')
替换为类似于
if''u ubuffer'的内容

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))

@maciejgol提出的方法非常好,但它不能处理超类不定义自定义
\uuuu getattr\uuuu
的常见情况(至少对于Python3)。为了避免此类问题,最好先使用始终定义的
\uuuuuGetAttribute\uuuuuu
进行检查,如果失败,则返回到
\uGetAttr

如果您事先不知道基类是否实现了自定义的
\uuu getattr\uuu
方法,我建议您这样做:

但在大多数情况下,仅使用
\uuu getattribute\uuu
就足够了:

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))

非常感谢。我怎样才能修复它?我更喜欢这种方式。它的侵入性较小(不需要挖掘内部的
\uuuuu dict\uuuu
属性),它更便于移植,因为它也适用于使用
\uuuu slots\uuuu
而不是
\uu dict\uuuuu
的类,而且速度更快(建议确保
try…catch…
块,而不是
if…else…
如果它永远不会失败)。
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))