我试图在类中的某些方法上实现一个装饰器,因此如果该值尚未被计算,则该方法将计算该值,否则它将返回预先计算的值,该值存储在实例defaultdict中。我似乎不知道如何从类之外声明的装饰器内部访问实例cc。对如何实施这个有什么想法吗?
以下是导入(对于一个工作示例):

from collections import defaultdict
from math import sqrt

这是我的装饰师:
class CalcOrPass:
    def __init__(self, func):
        self.f = func

    #if the value is already in the instance dict from SimpleData,
    #don't recalculate the values, instead return the value from the dict
    def __call__(self, *args, **kwargs):

        # can't figure out how to access/pass dict_from_SimpleData to here :(
        res = dict_from_SimpleData[self.f.__name__]
        if not res:
            res = self.f(*args, **kwargs)
            dict_from_SimpleData[self.f__name__] = res
        return res

下面是带修饰方法的SimpleData类:
class SimpleData:
    def __init__(self, data):
        self.data = data
        self.stats = defaultdict() #here's the dict I'm trying to access

    @CalcOrPass
    def mean(self):
        return sum(self.data)/float(len(self.data))

    @CalcOrPass
    def se(self):
        return [i - self.mean() for i in self.data]

    @CalcOrPass
    def variance(self):
        return sum(i**2 for i in self.se()) / float(len(self.data) - 1)

    @CalcOrPass
    def stdev(self):
        return sqrt(self.variance())

到目前为止,我试着在simpledata中声明装饰者,试着和装饰者进行多次争论(显然你不能这么做),在我的转椅上转来转去,同时试着把纸飞机扔进我的蝎子坦克。任何帮助都将不胜感激!

最佳答案

定义装饰器的方式目标对象信息丢失。改用函数包装器:

def CalcOrPass(func):
    @wraps(func)
    def result(self, *args, **kwargs):
        res = self.stats[func.__name__]
        if not res:
            res = func(self, *args, **kwargs)
            self.stats[func.__name__] = res
        return res
    return result

wraps是从functools开始的,在这里并不严格必要,但非常方便。
旁注:defaultdict采用工厂函数参数:
defaultdict(lambda: None)

但是,既然你正在测试密钥的存在,你应该选择一个简单的dict

10-07 14:51