繁体   English   中英

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

[英]Maximum recursion depth error in the python function

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)

hasattr调用__getattr__会导致递归。 从文档

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

解决此问题的一种方法可能是将if hasattr(self, '_ubuffer')替换为if '_ubuffer' in self.__dict__

您可以使用超类实现进行常规属性访问:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM