gpt4 book ai didi

python可重置实例方法内存装饰器

转载 作者:太空狗 更新时间:2023-10-29 20:22:08 32 4
gpt4 key购买 nike

我正在尝试为一个将记住结果的类的实例方法构建一个装饰器。 (这已经做过一百万次了)但是,我想要能够在任何时候重置内存缓存的选项(比如,如果实例状态中的某些内容发生变化,这可能会改变没有任何方法的结果与其参数有关)。因此,我尝试将装饰器构建为类而不是函数,这样我就可以作为类成员访问缓存。这让我走上了学习描述符的道路,特别是 __get__ 方法,这正是我真正陷入困境的地方。我的代码如下所示:

import time

class memoized(object):

def __init__(self, func):
self.func = func
self.cache = {}

def __call__(self, *args, **kwargs):

key = (self.func, args, frozenset(kwargs.iteritems()))

try:
return self.cache[key]
except KeyError:
self.cache[key] = self.func(*args, **kwargs)
return self.cache[key]
except TypeError:
# uncacheable, so just return calculated value without caching
return self.func(*args, **kwargs)

# self == instance of memoized
# obj == instance of my_class
# objtype == class object of __main__.my_class
def __get__(self, obj, objtype=None):
"""Support instance methods"""
if obj is None:
return self

# new_func is the bound method my_func of my_class instance
new_func = self.func.__get__(obj, objtype)

# instantiates a brand new class...this is not helping us, because it's a
# new class each time, which starts with a fresh cache
return self.__class__(new_func)

# new method that will allow me to reset the memoized cache
def reset(self):
print "IN RESET"
self.cache = {}

class my_class:
@memoized
def my_func(self, val):
print "in my_func"
time.sleep(2)
return val


c = my_class()

print "should take time"
print c.my_func(55)
print

print "should be instant"
print c.my_func(55)
print

c.my_func.reset()

print "should take time"
print c.my_func(55)

这是否明确和/或可能?每次调用 __get__ 时,我都会得到一个全新的内存类实例,它会丢失包含实际数据的缓存。我一直在努力使用 __get__,但没有取得太大进展。

是否有一种完全独立的方法来解决我完全想念的这个问题?欢迎和赞赏所有建议/建议。谢谢。

最佳答案

我没有试图找出实现的机制,而是从 PythonDecoratorLibrary 中获取了 memoized 装饰器类, 并对其进行了修改以添加 reset。以下是结果;我使用的技巧是向装饰函数本身添加一个可调用的 reset 属性。

    class memoized2(object):
"""Decorator that caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned, and
not re-evaluated.
"""
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
try:
return self.cache[args]
except KeyError:
value = self.func(*args)
self.cache[args] = value
return value
except TypeError:
# uncachable -- for instance, passing a list as an argument.
# Better to not cache than to blow up entirely.
return self.func(*args)
def __repr__(self):
"""Return the function's docstring."""
return self.func.__doc__
def __get__(self, obj, objtype):
"""Support instance methods."""
fn = functools.partial(self.__call__, obj)
fn.reset = self._reset
return fn
def _reset(self):
self.cache = {}


class my_class:
@memoized2
def my_func(self, val):
print "in my_func"
time.sleep(2)
return val


c = my_class()

print "should take time"
print c.my_func(55)
print

print "should be instant"
print c.my_func(55)
print

c.my_func.reset()

print "should take time"
print c.my_func(55)

关于python可重置实例方法内存装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4431703/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com