我的类装饰器中的_getattr_上的Python递归

时间:2017-03-17 14:08:55

标签: python recursion getattr

我编写了一个函数(Python 3.x),将其用作类装饰器,而不是将属性设置为private或public。 首先,我写了“私人”功能:

def private(attrlist):
    def wrapper(obj):
        class fPrivate:
            def __init__(self,*args,**kwargs):
                self.__wrapped = obj(*args,**kwargs)
            def __getattr__(self,args):
                if attrlist(args):
                    raise TypeError('Get on a provate attr')
                else:
                    return getattr(self.__wrapped,args)
            def __setattr__(self,args,val):
                if args == '_fPrivate.__wrapped':
                    self.__dict__[args] = val
                elif attrlist(args):
                    raise TypeError('Set on private')
                else:
                    setattr(self.__wrapped,args,val)
        return fPrivate
    return wrapper

然后我使用两种不同的方法来声明Private和Pubblic方法,如下所示:

def setPriv(*lists):
    return private(attrlist=(lambda args: args in lists))
def setPub(*lists):
    return private(attrlist=(lambda args: args not in lists))

此时我测试了我的工作:

@setPriv('name')
class t1:
    def __init__(self,name,age):
        self.name = name
        self.age = age

但是当我创建我的第一个实例时

a = t1('Bob',40)

我收到了这个错误:

> File "C:\Code\utils\private.py", line 11, in __getattr__
getattr(self.__wrapped,args)
File "C:\Code\utils\private.py", line 11, in __getattr__
getattr(self.__wrapped,args)
File "C:\Code\utils\private.py", line 11, in __getattr__
getattr(self.__wrapped,args)
File "C:\Code\utils\private.py", line 11, in __getattr__
getattr(self.__wrapped,args)
File "C:\Code\utils\private.py", line 8, in __getattr__
if attrlist(args):
File "C:\Code\utils\private.py", line 25, in <lambda>
return private(attrlist=(lambda args: args in lists))
RecursionError: maximum recursion depth exceeded in comparison

提前致谢

1 个答案:

答案 0 :(得分:1)

在属性名称​​ mangled 之后,仍然遵循Python命名规则,因此属性__wrapped将显示为_fPrivate__wrapped而不是_fPrivate.__wrapped ;没有点。

如果您检查追溯,当您第一次尝试设置__init__时,您会看到self.__wrapped中出现错误,即转弯__getattribute__然后{{1自__getattr__再次包含属性访问即可。 __getattr__,它一直在继续。

删除该点可确保self.__wrapped使其成为实例字典并设置属性调用_fPrivate__wrapped,该属性调用可以干净地返回属性,而无需进行更深入的搜索。

__getattribute__