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
示例:下面的代码使用foo_register
来修饰my_function
,而不是使用decorator
。
@foo_register
def my_function():
print('hi...')
示例:下面的代码按预期工作。
@foo_register('say_hi')
def my_function():
print('hi...')
如果我想让它在两个应用程序中都能正常工作(一个使用method.__name__
,另一个传入名称),我必须在foo_register
内部检查第一个参数是否是一个装饰器,如果是的话,我必须这样做:return decorator(method_name)
(而不是return decorator
)。这种“检查一下它是否是可调用的”看起来非常老土。有没有更好的方法来创建这样的多用途装饰器?
附注:我已经知道我可以要求调用装饰器,但这不是一个“解决方案”。我希望API看起来很自然。我妻子喜欢装饰,我不想破坏这一点。
发布于 2010-10-08 14:38:25
格伦--我不得不这么做。我想我很高兴没有一个“神奇”的方法来做到这一点。我讨厌这些。
因此,这是我自己的答案(方法名称与上面不同,但概念相同):
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
示例用法(两个版本的用法相同):
@register_gw_method
def my_function():
print('hi...')
@register_gw_method('say_hi')
def my_function():
print('hi...')
发布于 2012-04-24 05:33:50
怎么样
from functools import wraps, partial
def foo_register(method=None, string=None):
if not callable(method):
return partial(foo_register, string=method)
method.gw_method = string or method.__name__
@wraps(method)
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
发布于 2012-04-24 05:59:32
现在,这个旧的线程又回到了顶端,让我只抛出一些Decorator-ception:
def magical_decorator(decorator):
@wraps(decorator)
def inner(*args, **kw):
if len(args) == 1 and not kw and callable(args[0]):
return decorator()(args[0])
else:
return decorator(*args, **kw)
return inner
现在你神奇的装饰器只有一行之遥了!
@magical_decorator
def foo_register(...):
# bla bla
顺便说一句,这对任何装饰者都适用。它只会使@foo
的行为(尽可能接近)像@foo()
一样。
https://stackoverflow.com/questions/3888158
复制相似问题