在装饰器中使用自变量
Posted
技术标签:
【中文标题】在装饰器中使用自变量【英文标题】:Use Self Variable in Decorator 【发布时间】:2022-01-16 04:06:05 【问题描述】:我正在尝试为我的程序使用缓存,我想让用户选择程序应该缓存多长时间。
class Parent:
"""The Parent Class, Do not import this."""
def __init__(self, apiKey, cacheTime=300):
self.key = apiKey
self.time = cacheTime
class invalidApiKey(Exception):
"""The invalidApiKey error."""
def __init__(self, *args):
self.message = args[0]
def __str__(self):
return "Invalid API Key (Register at https://url.com/register)- 0 ".format(
self.message
)
class Child(Parent):
@cached(cache=TTLCache(maxsize=1024, ttl=Parent.time))
async def requestStats(self):
这就是我的代码的样子,我尝试过使用全局变量、环境变量、我自己的装饰器-
class Parent:
def cache(f):
def wrapper(*args):
return cached(cache=TTLCache(maxsize=1024, ttl=args[0].time))
return wrapper
class Child(Parent):
@Parent.cache
async def requestStats(self):
但我收到了ValueError: a coroutine was expected, got <function cached.<locals>.decorator at 0x7f8b5d1e3c10>
,我现在不确定如何继续。
TL:DR - 我想使用父类中的 self 变量作为子类中函数的参数。 (如果有影响,我使用this library 进行缓存)
【问题讨论】:
请显示complete 异常回溯,从Traceback (most recent call last):
行开始,格式为代码。
这不是我感兴趣的错误,我只是解释了我在尝试可能的修复时收到的错误,我只是想知道如何在这种情况下使用自变量。你去吧编辑 - 我不知道如何在评论中格式化代码,你去 - mystb.in/PoorAccountHandy.sql
有什么更新吗?这对我来说有点重要,我很想看看如何管理它:)
【参考方案1】:
我可能是错的,但在我看来,你把它复杂化了。您似乎想要一个在实例化而不是定义时参数化的装饰。如果你想使用cached
,那么你可以这样做:
from cachetools import TTLCache, cached
class Foo:
def __init__(self, time=600):
self.bar = cached(TTLCache(maxsize=1024, ttl=time))(self.bar)
def bar(self):
...
这里未修饰的方法是在定义时创建的,然后在实例化时用各自的参数 - time
进行修饰。但这有点尴尬,我觉得更好的办法是使用cachedmethod
:
from cachetools import TTLCache, cachedmethod
class Foo:
def __init__(self, time=600):
self.cache = TTLCache(maxsize=1024, ttl=time)
@cachedmethod(lambda self: self.cache)
def bar(self):
...
这里的修饰发生在定义处,但使用 cache
-function 引用在实例化时设置的缓存对象 - self.cache
- 带有单独的参数。
但是:你确定cachetools
可以处理asyncio
?
【讨论】:
我不确定 cachetools 是否可以处理 asyncio,但它现在似乎工作正常,我会试试你的解决方案,明天再来,ty!以上是关于在装饰器中使用自变量的主要内容,如果未能解决你的问题,请参考以下文章