首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使参数在python装饰器中可配置?

如何使参数在python装饰器中可配置?
EN

Stack Overflow用户
提问于 2020-03-02 19:16:57
回答 2查看 343关注 0票数 1

我正在使用缓存工具进行一些基本的缓存。下面是我如何使用它的一个例子:

代码语言:javascript
复制
class Access:

  @cached(cache=TTLCache(maxsize=5, ttl=10))
  def get_some_value(input: str):
    # do some calls and return a value

这里的问题是如何使maxsizettl可配置?我不能做像

代码语言:javascript
复制
class Access:
  def __init__(self, maxsize: int = 5, ttl: int = 10):
    self.maxsize = maxsize
    self.ttl = ttl

  @cached(cache=TTLCache(maxsize=self.maxsize, ttl=self.ttl))
  def get_some_value(input: str):
    # do some calls and return a value

如果需要的话,我正在寻找注入这些值的方法,并且也有一个缺省值。有什么有用的建议吗?另外,get_some_value()不一定是一个实例方法。如果需要的话,我也可以让它成为类、方法或模块级别。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-02 19:25:31

为了解决这个问题,我们可以使用Python装饰器只是返回其他函数的函数。

假设您有一个eggs装饰器:

代码语言:javascript
复制
def eggs(foo=10, bar=20):
    def wrapper_gen(func):
        def wrapper(*args):
            print(foo, bar)
            func(*args)
        return wrapper
    return wrapper_gen

这个Spam类:

代码语言:javascript
复制
class Spam:
    @eggs(foo=10, bar=20)
    def baz(self, input):
        print(input)

我们可以这样调用baz方法:

代码语言:javascript
复制
Spam().baz("Hello, world!")

这给了我们

代码语言:javascript
复制
10 20
Hello, world!

现在,我们不再直接修饰函数,而是使用我们的__init__方法来装饰:

代码语言:javascript
复制
class Spam:
    def __init__(self, foo=10, bar=20):
        self.baz = eggs(foo=foo, bar=bar)(self._baz_func)

    def _baz_func(self, input):
        print(input)

现在:

代码语言:javascript
复制
Spam(foo=20, bar=30).baz("Hello, world!")

这输出

代码语言:javascript
复制
20 30
Hello, world!

这样做的原因是:

代码语言:javascript
复制
@foo
def bar():
    ...

是这个词的缩写:

代码语言:javascript
复制
def bar():
    ...

bar = foo(bar)
票数 2
EN

Stack Overflow用户

发布于 2020-03-02 19:26:45

这不能使用常规的修饰器语法,原因有两个:get_some_value属于类,因此它不能对不同的实例有不同的行为,因为只有一个它的“副本”;装饰器是在类声明时执行的,而不是在创建实例时执行的,因此还没有__init__参数。

但是,可以通过显式地在__init__方法中应用装饰器来获得所需的结果:

代码语言:javascript
复制
class Access:
    def __init__(self, maxsize: int = 5, ttl: int = 10):
        decorator = cached(cache=TTLCache(maxsize=maxsize, ttl=ttl))
        self.get_some_value = decorator(self.get_some_value)

    def get_some_value(self, input: str):
        ...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60495260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档