2016-10-25 74 views
0

这是我实现memoize的的:memoize的上课,其初始化具有超()初始化

猫test.py

def _memoize(obj): 
    cache = obj.cache = {} 

    @functools.wraps(obj) 
    def memoizer(*args, **kwargs): 
     key = str(args) + str(kwargs) 
     if key not in cache: 
      cache[key] = obj(*args, **kwargs) 
     return cache[key] 
    return memoizer 

@_memoize 
class Test(object): 
    def __init__(self, arg1): 
     super(Test, self).__init__() 
     self.arg = arg1 
     print "init executed for " + arg1 

    def authenticate(self): 
     print self.arg 

t1 = Test('a') 

当我运行此我得到以下错误:

$蟒蛇test.py

Traceback (most recent call last): 
    File "test.py", line 23, in <module> 
    t1 = Test('a') 
    File "test.py", line 9, in memoizer 
    cache[key] = obj(*args, **kwargs) 
    File "test.py", line 16, in __init__ 
    super(Test, self).__init__() 
TypeError: super() argument 1 must be type, not function 

您能否建议如何解决这个错误?

+0

所以当'x == y'(或者至少当'hash(x)== hash(y)')时,总是希望'Test(x)是Test(y)'是真的吗? – chepner

回答

0

functools.wraps是一个方便的功能包装,并使用装饰是like wrapping Test in that function call;

Test = _memoize(Test) 

所以,测试不再是一个类,它是一个函数,并作为错误表示super不想要funtion。

我不明白你的意图足以提出一个替代方案。

1

在你的memoizer函数中,你需要创建一个新类型;你正在创建和返回一个函数,并且这样做可以让你的类变成一个函数。一个更简单的方法来完成你想要做的事情是重写__new__,它允许你在分配对象之前拦截对构造函数的调用,所以你可以这样做(简化,但是你可以在这里复制你的多参数处理太):

class Test(object): 
    def __init__(self, arg): 
     self.x = arg 

    _cache = {} 
    def __new__(cls, arg): 
     if arg not in _cache: 
      _cache[arg] = cls(arg) 
     return _cache[arg] 

如果你想要更多的东西装饰风格,你可以看看__metaclass__,它允许你做类似的事情在更轻松地在共享的类继承没有一种方式。