我正在尝试为将记住结果的类的实例方法构建装饰器。(这已经完成了一百万次了)但是,我希望可以在任何时候重置已记忆的缓存(例如,如果实例状态中的某些内容发生了更改,这可能会更改没有任何内容的方法的结果)与它的参数有关)。因此,我尝试将装饰器构建为类而不是函数,以便我可以作为类成员访问缓存。这使我走下了学习描述符的道路,特别是__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__
,但进展不大。
我是否完全没有针对此问题的完全独立的方法?并欢迎所有建议/建议。谢谢。
我没有尝试弄清实现的机制,而是memoized
从PythonDecoratorLibrary获取了decorator类,并将其修改为add
reset
。结果如下:我使用的技巧是reset
在装饰后的函数本身中添加一个callable属性。
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)
问题内容: 考虑这个小例子: 哪个打印 为什么参数(应该是Test obj实例)没有作为第一个参数传递给装饰函数? 如果我手动进行操作,例如: 它按预期工作。但是,如果我必须事先知道某个函数是否装饰,它就破坏了装饰器的全部目的。这里的模式是什么,还是我误会了什么? 问题答案: tl; dr 您可以通过将类作为描述符并返回部分应用的函数来解决此问题,该函数从中应用对象作为参数之一,如下所示 实际问题
本文向大家介绍vue.js实现备忘录功能的方法,包括了vue.js实现备忘录功能的方法的使用技巧和注意事项,需要的朋友参考一下 这个vue实现备忘录的功能demo是K在github上找到的,K觉得这是一个用来对vue.js入门的一个非常简单的demo,所以拿在这里共享一下。 (尊重他人劳动成果,从小事做起~ demo原github地址:https://github.com/vuejs/vue)
本文向大家介绍基于Python 装饰器装饰类中的方法实例,包括了基于Python 装饰器装饰类中的方法实例的使用技巧和注意事项,需要的朋友参考一下 title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] category: ['Python'] --- 目前在中文网
本文向大家介绍JS操作COOKIE实现备忘记录的方法,包括了JS操作COOKIE实现备忘记录的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS操作COOKIE实现备忘记录的方法。分享给大家供大家参考,具体如下: 具体涉及JS针对cookie的写入与获取操作,代码如下: 更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript查找算法技巧总结》、《Jav
本文向大家介绍C#备忘录模式(Memento Pattern)实例教程,包括了C#备忘录模式(Memento Pattern)实例教程的使用技巧和注意事项,需要的朋友参考一下 本文以一个简单实例讲述了C#备忘录模式(Memento Pattern)的实现方法。分享给大家供大家参考。具体实现方法如下: 简单来说,备忘录模式就是支持回退操作。假设让一个Notepad支持回退操作,如何实现呢? 首先需要
本文向大家介绍Vue.js实现备忘录功能,包括了Vue.js实现备忘录功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Vue.js实现备忘录的具体代码,供大家参考,具体内容如下 效果展示: html代码: CSS代码: js代码: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
主要内容:介绍,实现,Memento.java,Originator.java,CareTaker.java,MementoPatternDemo.java备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 介绍 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 介绍 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 主要解决:所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。 何时使用:很多时候我们总是需要记录一个对象