我可以用python将动态值传递给decorator吗?

2024-05-15 06:02:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我对python及其概念有点陌生。对于我当前的项目,我需要以x速率/y分钟执行某些api调用。 关于这一点,我遇到了decorator的概念和一个python库。 它名为ratelimit,然后单击here转到它的github链接

此api最简单的示例是:

from ratelimit import rate_limited
import requests

MESSAGES=100
SECONDS= 3600

@rate_limited(MESSAGES, SECONDS)
def call_api(url):
    response = requests.get(url)

   if response.status_code != 200:
     raise ApiError('Cannot call API: {}'.format(response.status_code))
   return response

但我需要从另一个函数调用这个函数call_api

^{2}$

我希望调用发生,并希望decorator的参数在运行时更新,因为实际值将是用户输入。 但根据我的理解,decorator在运行时之前会先获取值。那么如何将动态值传递给decorator呢。在

感谢您的帮助


Tags: importapi概念urlrateresponsestatuscode
2条回答

decorator可以随时使用,而不仅仅是在定义函数时。你不能使用decorator语法。在

# undecorated
def call_api(url):
    response = requests.get(url)
    if response.status_code != 200:
        raise ApiError('Cannot call API: {}'.format(response.status_code))
    return response

def send_message():
    global MESSAGES
    global SECONDS
    MESSAGES=10
    SECONDS=5
    end_time=time.time()+60 #the end time is 60 seconds from the start time

    rl_api = rate_limited(MESSAGES, SECONDS)(call_api)
    while(time.time()<end_time):
        rl_api(url)

这意味着您可以同时创建多个速率受限函数,使用rate_limited的不同参数。在

^{pr2}$

您的问题基本上是是否可以通过引用而不是按值调用装饰器。答案是yes。执行摘要:传递一个可变对象。在

在这种情况下,这对你没有任何好处。正如您在ratelimit模块的code中看到的,在定义修饰函数时,every和{}这两个参数用于设置新变量frequency

frequency = abs(every) / float(clamp(period))

为了获得一个可变频率,你必须重写模块来支持你的需求,但这应该是可行的。请将以下内容作为最低限度的说明:

^{pr2}$

现在旋转一下:

>>> l = Limiter(1, 2)
>>> 
>>> @limit(l)
... def foo():
...     pass
... 
>>> foo()
2 1
>>> l.every = 10
>>> foo()
2 10

相关问题 更多 >

    热门问题