用可选参数制作装饰器 [英] Making decorators with optional arguments
问题描述
from functools import wraps
def foo_register(method_name=None):
"""Does stuff."""
def decorator(method):
if method_name is None:
method.gw_method = method.__name__
else:
method.gw_method = method_name
@wraps(method)
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
return decorator
示例:以下代码用<$ c $装饰 my_function
c> foo_register 而不是让它成为装饰器
。
Example: The following decorates my_function
with foo_register
instead of ever making it to decorator
.
@foo_register
def my_function():
print('hi...')
示例:以下操作符合预期。
Example: The following works as expected.
@foo_register('say_hi')
def my_function():
print('hi...')
如果我希望它在两个应用程序中都能正常工作离子(一个使用方法。__name __
,一个传入名称),我必须检查 foo_register
的内部以查看如果第一个参数是装饰器,如果是,则必须:返回装饰器(方法名称)
(而不是返回装饰器
)。这种检查是否可以通话似乎非常骇人听闻。有没有更好的方法来创建这样的多用途装饰器?
If I want it to work correctly in both applications (one using method.__name__
and one passing the name in), I have to check inside of foo_register
to see if the first argument is a decorator, and if so, I have to: return decorator(method_name)
(instead of return decorator
). This sort of "check to see if it's a callable" seems very hackish. Is there a nicer way to create a multi-use decorator like this?
P.S。我已经知道我可以要求装饰器被调用,但这不是一个解决方案。我希望API感觉自然。我的妻子喜欢装饰,所以我不想破坏它。
P.S. I already know that I can require the decorator to be called, but that's not a "solution". I want the API to feel natural. My wife loves decorating, and I don't want to ruin that.
推荐答案
Glenn-然后,我必须这样做。我想我很高兴没有一种神奇的方式来做到这一点。我讨厌那些。
Glenn - I had to do it then. I guess I'm glad that there is not a "magic" way to do it. I hate those.
所以,这是我自己的答案(方法名称与上面不同,但概念相同):
So, here's my own answer (method names different than above, but same concept):
from functools import wraps
def register_gw_method(method_or_name):
"""Cool!"""
def decorator(method):
if callable(method_or_name):
method.gw_method = method.__name__
else:
method.gw_method = method_or_name
@wraps(method)
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
if callable(method_or_name):
return decorator(method_or_name)
return decorator
用法示例(两个版本都相同):
Example usage (both versions work the same):
@register_gw_method
def my_function():
print('hi...')
@register_gw_method('say_hi')
def my_function():
print('hi...')
这篇关于用可选参数制作装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!