限速 python 装饰器

Rate-limiting python decorator

我发现 this 限速 python 装饰器基于 redis 类。我怎样才能编写一个类似的装饰器,它只使用标准库中可用的装饰器,可以按如下方式使用?

def ratelimit(limit, every):
    #  python magic 

@ratelimit(limit=1, every=2)
def printlimited(x):
    print x

# print one number every two seconds
for x in range(10):
    printlimited(x)

Whosebug 上还有其他 answers 但它们不允许指定分母。

您可以使用 threading.Semaphore to count and block the requests that are exceeding the limit, in combination with threading.Timer 来安排释放信号量的函数。

from threading import Semaphore, Timer
from functools import wraps

def ratelimit(limit, every):
    def limitdecorator(fn):
        semaphore = Semaphore(limit)
        @wraps(fn)
        def wrapper(*args, **kwargs):
            semaphore.acquire()
            try:
                return fn(*args, **kwargs)
            finally:                    # don't catch but ensure semaphore release
                timer = Timer(every, semaphore.release)
                timer.setDaemon(True)   # allows the timer to be canceled on exit
                timer.start()
        return wrapper
    return limitdecorator

我扩展了这个想法并在 PyPI 上发布了一个名为 limit 的库。