python - 如何将内存装饰器应用于实例方法?

标签 python python-3.x python-decorators

我想在类方法上使用内存装饰器。 cExample.pri() 调用self.text()memorize 似乎不知道self。当 memorize 调用 self.func(*key) 时,它缺少 cExample obj,因此它提示缺少 args。

我如何更改这个 memorize 装饰器,以便它能够将调用者的 self 传递给函数?

Python3.5.2

class memorize(dict):
    def __init__(self, func):
        self.func = func

    def __call__(self, *args):
        return self[args]

    def __missing__(self, key):
        result = self[key] = self.func(*key)
        return result

class cExample():
    @memorize
    def pri(self, text):
        return self.text(text)

    def text(self, text):
        return text

c = cExample()
print(c.pri('hi'))

输出:

Traceback (most recent call last):
  File "x.py", line 23, in <module>
    print(c.pri('hi'))
  File "x.py", line 7, in __call__
    return self[args]
  File "x.py", line 11, in __missing__
    result = self[key] = self.func(*key)
TypeError: pri() missing 1 required positional argument: 'text'

最佳答案

您需要将self(即c)传递给cExample.pri(即self.func) .但是 __missing__ 不允许您这样做:它只接收 key 。

您可以使用基于函数的装饰器重写它:

import functools

def memorize2(f):
    cache = {}
    @functools.wraps(f)
    def wrapper(*args):
        if args not in cache:
            cache[args] = f(*args)
        return cache[args]
    return wrapper

class cExample():
    @memorize2
    def pri(self, text):
        return self.text(text)

    def text(self, text):
        return text

c = cExample()
print(c.pri('hi'))  # hi

(我使用 functools.wraps 不丢失装饰方法的原始名称)。

在这种方法中,self 将作为位置参数传递给 wrapper 并代理到 cExample.pri

关于python - 如何将内存装饰器应用于实例方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51138226/

相关文章:

python - 在 python 中的空白处切割 x 个字符后的字符串

python - 曲线拟合问题,exp遇到溢出

python - 平方根 : ValueError: math domain error

python - 安装pybind11后"No module named pybind11"

python - 有没有办法将属性添加到函数作为函数定义的一部分?

python - functools.wraps 相当于类装饰器

python - python装饰器是否立即调用返回的回调?

python - 类型错误 : 'NoneType' object is not iterable when applying decorator to generator

python - 如何根据唯一列组合 Pandas 数据框

python - 了解可变变量的函数作用域