Mar*_*nen 2 python decorator python-3.x python-decorators
我正在创建一个装饰器,该装饰器将允许我执行以下操作:
@cooldownf(lambda self, **eargs: 30 - self.level)
def method(self, **eargs):
...
Run Code Online (Sandbox Code Playgroud)
这将简单地装饰方法,使其具有冷却时间。所有这些工作都很好,并且该方法现在可以每秒钟执行一次30 - self.level。
但是,我想添加一条消息,如果该方法仍处于冷却状态,则会显示该消息。我message为cooldownf装饰器添加了一个参数,但是随后我的装饰器代码UnboundLocalError: local variable 'message' referenced before assignment行ìf message:中出现错误:
def cooldownf(fn, message=None):
"""Decorates a method to have a dynamic cooldown.
Decorator function for easily adding cooldown as a dynamic time
(function) into skill's methods. The function gets called when the
cooldown is needed, and the skill is passed to the function.
Args:
fn: Function to determine the cooldown of the method
message: Optional message sent if there's still cooldown left
Returns:
Decorated method with a dynamic cooldown
"""
# Create a decorator using the function and message provided
def method_decorator(method):
# Create a wrapper method
@wraps(method, assigned=WRAPPER_ASSIGNMENTS+('__dict__',), updated=())
def method_wrapper(self, **eargs):
# If the method's cooldown is over
if method_wrapper.cooldown.remaining <= 0:
# Restart the cooldown
method_wrapper.cooldown.start(1, fn(self, **eargs))
# And call the function
return method(self, **eargs)
# If there was cooldown remaining and a message is provided
if message:
# Format the provided message
message = message.format(
name=self.name,
cd=method_wrapper.cooldown.remaining,
max_cd=method_wrapper.cooldown.limit
)
# Send it to the player
SayText2(message=message).send(eargs['player'].index)
# And exit with code 3
return 3
# Create the cooldown object for the wrapper
method_wrapper.cooldown = TickRepeat(lambda: None)
# And return the wrapper
return method_wrapper
# Return the decorator
return method_decorator
Run Code Online (Sandbox Code Playgroud)
是什么原因造成的?我可以message在cooldownf或中method_decorator进行打印,但在中添加打印内容method_wrapper会引起错误。那是精确的代码,我无法使用函数将其复制到IDLE中,特别是使用方法与我有什么关系吗?
您要分配给method最里面的功能:
message = message.format(
name=self.name,
cd=method_wrapper.cooldown.remaining,
max_cd=method_wrapper.cooldown.limit
)
Run Code Online (Sandbox Code Playgroud)
该分配使它成为局部变量,但是您必须先访问才能进行分配message。您无法通过本地方式做到这一点。
由于您不想修改closed-over参数,因此您想在此处使用新的本地名称:
formatted_message = message.format(
name=self.name,
cd=method_wrapper.cooldown.remaining,
max_cd=method_wrapper.cooldown.limit
)
SayText2(message=formatted_message).send(eargs['player'].index)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1332 次 |
| 最近记录: |