用可选参数制作装饰器 [英] Making decorators with optional arguments

查看:68
本文介绍了用可选参数制作装饰器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆