【问题标题】:How to create a cooldown decorator如何创建冷却装饰器
【发布时间】:2019-11-30 11:52:18
【问题描述】:

我正在尝试在 Python 3 中创建一个冷却装饰器。理想的用法如下:

@cooldown(duration=2)
def func(string):
  print(string)

那么……

func('1st attempt') # should work (as cooldown == 0) and reset cooldown (cooldown = 2)
func('2nd attempt') # should fail (as cooldown != 0)
func.update_cooldown() # should decrease cooldown (cooldown -= 1)
func('3rd attempt') # should also fail (as cooldown != 0)
func.update_cooldown() # should decrease cooldown (cooldown -= 1)
func('4th attempt') # should work (as cooldown == 0) and reset cooldown (cooldown = 2)

我的代码(Python 3.8):

import functools

def cooldown(duration):
    def decorator(method):
        cooldown = 0

        @functools.wraps(method)
        def wrapper(*args, **kwargs):
            nonlocal cooldown
            if cooldown <= 0:
                cooldown = duration
                return method(*args, **kwargs)
            print(f'Cooldown active, {cooldown} updates remaining')

        return wrapper
    return decorator

如何为特定装饰功能添加减少冷却时间的功能?以及如何使其适应类方法?

提前致谢!

【问题讨论】:

    标签: python python-3.x decorator python-decorators


    【解决方案1】:
    def cooldown(duration):
        def decorator(method):
            cooldown = 0
    
            @functools.wraps(method)
            def wrapper(*args, **kwargs):
                nonlocal cooldown
                if cooldown <= 0:
                    cooldown = duration
                    return method(*args, **kwargs)
                print(f"Cooldown active, {cooldown} updates remaining")
    
            def update_cooldown():
                nonlocal cooldown
                cooldown -= 1
    
            wrapper.update_cooldown = update_cooldown
            return wrapper
    
        return decorator
    

    cooldown 变量对于每个装饰函数都是唯一的,因为在每个冷却调用中,您都定义了新的装饰函数 def decorator(method):,并在内部定义了新的冷却计数器。

    它已经适用于类方法:

    class A:
        @classmethod
        @cooldown(duration=2)
        def a(cls):
            print("whatever")
    
    A.a() # whatever
    A.a() # Cooldown active, 2 updates remaining
    A.a.update_cooldown() 
    A.a() # Cooldown active, 1 updates remaining
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-04
      • 2016-08-17
      • 1970-01-01
      • 2023-04-01
      • 2021-05-09
      • 2014-02-13
      • 2012-08-02
      • 1970-01-01
      相关资源
      最近更新 更多