[英]Memoization Decorator
我有以下伪代码:
class myClass()
def slow_method(self):
try:
return self.memo_slow_method
except:
self.memo_slow_method = some_slow_function()
return self.memo_slow_method
是否有可能构建一个完全执行此逻辑的memoization装饰器?
限制:
self
参数 - 不会传递任何参数。 PS我一直在使用@lrucache,但它不适合我的目的。 它确实需要完全遵循上述逻辑。
您可以使用描述符(类似属性)而不是装饰器:
class Memoize(object):
def __init__(self, name, func):
self.name = name # name of the memo attribute
self.func = func # the function that is executed when there is no memo
def __get__(self, obj, typ=None):
if obj:
try:
return getattr(obj, self.name)
except:
setattr(obj, self.name, self.func())
return getattr(obj, self.name)
else:
return self
然后设置描述符:
class Fun(object):
meth = Memoize('x', lambda: print('in') or 10)
然后是互动测试:
>>> f = Fun()
>>> f.meth # function is executed
'in'
10
>>> f.x
10
>>> f.meth # function is not executed
10
如果你真的想要一个装饰者:
def memoize(func):
def inner(self):
try:
return self.memo_slow_method # hardcoded memo attribute name
except:
self.memo_slow_method = func(self) # execute the method body
return self.memo_slow_method
return inner
class Fun(object):
@memoize
def meth(self):
print('in')
return 100
>>> f = Fun()
>>> f.meth()
'in'
100
>>> f.meth()
100
>>> f.memo_slow_method
100
这是一个装饰器,可以根据要求准确地实现您的逻辑。 它通过向函数名称添加前缀来从函数名称(在func.__name__
可用)中为备注字段的名称func.__name__
:
from __future__ import print_function
import time
from functools import wraps
memo_prefix = '_memo_' # Check for possible name collision
def deco(func):
memo_field_name = memo_prefix + func.__name__
def ret_func(self):
try:
return getattr(self, memo_field_name)
except AttributeError:
ret_val = func(self)
setattr(self, memo_field_name, ret_val)
return ret_val
return ret_func
def some_slow_function():
for x in range(3):
time.sleep(1)
print('Waiting...', x)
return 'Done'
class myClass():
@deco
def slow_method(self):
return some_slow_function()
现在测试一下:
In [2]: it = myClass()
In [3]: print(it.slow_method())
Waiting... 0
Waiting... 1
Waiting... 2
Done
In [4]: print(it.slow_method())
Done
In [5]: print(it.__dict__)
{'_memo_slow_method': 'Done'}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.