python中的类Decorator装饰方法
我试图使用装饰器来记忆,装饰器是一个类而不是一个函数,但我收到错误,
TypeError: seqLength() takes exactly 2 arguments (1 given)
我猜这与类有关,但不确定那里出了什么问题。
代码:
import sys
class memoize(object):
'''memoize decorator'''
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
try:
return self.cache[args]
except KeyError:
value = self.func(self, *args)
self.cache[args] = value
return value
class collatz(object):
def __init__(self, n):
self.max = 1
self.n = n
@memoize
def seqLength(self, n):
if n>1:
if n%2 == 0:
return 1+self.seqLength(n/2)
else:
return 1+self.seqLength(3*n+1)
else:
return 1
def maxLength(self):
for n in xrange(1, self.n):
l = self.seqLength(n)
if l > self.max:
self.max = n
return self.max
n = int(sys.argv[1])
c = collatz(n)
print c.maxLength()
I'm trying to memoize using a decorator with the decorator being a class not a function, but I'm getting the error
TypeError: seqLength() takes exactly 2 arguments (1 given)
I'm guessing this has something to do with the classes, but not sure what's wrong from there.
The code:
import sys
class memoize(object):
'''memoize decorator'''
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
try:
return self.cache[args]
except KeyError:
value = self.func(self, *args)
self.cache[args] = value
return value
class collatz(object):
def __init__(self, n):
self.max = 1
self.n = n
@memoize
def seqLength(self, n):
if n>1:
if n%2 == 0:
return 1+self.seqLength(n/2)
else:
return 1+self.seqLength(3*n+1)
else:
return 1
def maxLength(self):
for n in xrange(1, self.n):
l = self.seqLength(n)
if l > self.max:
self.max = n
return self.max
n = int(sys.argv[1])
c = collatz(n)
print c.maxLength()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从语法上讲,这很令人困惑。目前尚不清楚 self.func 是您的 memoize 的一部分还是作为其他类的其他对象的一部分的单独函数。 (顺便说一句,你的意思是后者)
这样做是为了明确
the_func
只是一个函数,而不是 memoize 类的成员。这种事情可以防止对
self.
所绑定的类产生混淆。另外,请拼写它
Memoize
。以大写字母开头。毕竟,这是一个类定义。This is confusing, syntactically. It's not clear if
self.func
is part of your memoize or a separate function that's part of some other object of some other class. (You mean the latter, BTW)Do this to make it clear that
the_func
is just a function, not a member of the memoize class.That kind of thing prevents confusion over the class to which
self.
is bound.Also, please spell it
Memoize
. With a leading capital letter. It is a class definition, after all.使用类作为装饰器很棘手,因为您必须实现描述符协议< /a> 正确(当前接受的答案没有。)一个非常非常简单的解决方案是使用包装函数,因为它们会自动正确地实现描述符协议。与您的类等效的包装器将是:
当您有如此多的状态并且想要将其封装在类中时,您仍然可以使用包装器函数,例如如下所示:
Using a class as a decorator is tricky, because you have to implement the descriptor protocol correctly (the currently accepted answer doesn't.) A much, much easier solution is to use a wrapper function, because they automatically implement the descriptor protocol correctly. The wrapper equivalent of your class would be:
When have so much state you want to encapsulate it in a class anyway, you can still use a wrapper function, for example like so:
装饰器只是
foo =decorator(foo)
的语法糖,因此在这种情况下,您最终会将seqLength
的self
设为memoize
而不是collatz
。您需要使用描述符。此代码对我有用:有关描述符的更多信息:
http://docs.python.org /howto/descriptor.html#descriptor-example
A decorator is just syntactic sugar for
foo = decorator(foo)
, so in this case you're ending up making theself
ofseqLength
bememoize
instead ofcollatz
. You need to use descriptors. This code works for me:More on descriptors:
http://docs.python.org/howto/descriptor.html#descriptor-example