在装饰器中解析args和kwargs [英] Parsing args and kwargs in decorators

查看:110
本文介绍了在装饰器中解析args和kwargs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个接受args和kwargs的函数,我需要根据该函数中 2nd arg的值在装饰器中执行某些操作,如以下代码所示:

I've got a function that takes args and kwargs, and I need to do something in my decorator based on the value of the 2nd arg in the function, like in the code below:

def workaround_func():
    def decorator(fn):
        def case_decorator(*args, **kwargs):
            if args[1] == 2:
                print('The second argument is a 2!')
            return fn(*args, **kwargs)
        return case_decorator
    return decorator

@workaround_func()
def my_func(arg1, arg2, kwarg1=None):
    print('arg1: {} arg2: {}, kwargs: {}'.format(arg1, arg2, kwarg1))

问题是python允许用户使用第二个参数作为常规参数或关键字参数来调用函数,因此,如果用户使用 arg2调用 my_func , code>作为扭曲,会引发 IndexError ,如下所示:

The problem is that python allows users to call the function with the second argument as a regular argument OR a keyword-argument, so if the user calls my_func with arg2 as a kwarg, it raises an IndexError, see below:

In [8]: d.my_func(1, 2, kwarg1=3)
The second argument is a 2!
arg1: 1 arg2: 2, kwargs: 3

In [9]: d.my_func(1, arg2=2, kwarg1=3)
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-9-87dc89222a9e> in <module>()
----> 1 d.my_func(1, arg2=2, kwarg1=3)

/home/camsparr/decoratorargs.py in case_decorator(*args, **kwargs)
      2     def decorator(fn):
      3         def case_decorator(*args, **kwargs):
----> 4             if args[1] == 2:
      5                 print('The second argument is a 2!')
      6             return fn(*args, **kwargs)

IndexError: tuple index out of range

是否有解决此问题的方法,而不仅仅是做尝试/除外并捕获 IndexError

Is there a way around this without just doing a try/except and catch the IndexError?

推荐答案

我找到了使用python decorator 的答案软件包。该软件包的一个功能是,无论用户如何传递,它都会保留位置/关键字参数。它具有减少大量代码的额外好处,因此我的原始代码为:

I found an answer using the python decorator package. One feature of this package is that it preserves positional/keyword args no matter how the user passes them. It has the added benefit of reducing a lot of code, so my original code:

def workaround_func():
    def decorator(fn):
        def case_decorator(*args, **kwargs):
            if args[1] == 2:
                print('The second argument is a 2!')
            return fn(*args, **kwargs)
        return case_decorator
    return decorator

@workaround_func()
def my_func(arg1, arg2, kwarg1=None):
    print('arg1: {} arg2: {}, kwargs: {}'.format(arg1, arg2, kwarg1))

成为:

from decorator import decorator

@decorator
def workaround_decorator(f, *args, **kwargs):
    if args[1] == 2:
        print('The second argument is 2!')
    return f(*args, **kwargs)

@workaround_decorator
def my_func(arg1, arg2, kwarg1=None):
    print('arg1: {} arg2: {}, kwargs: {}'.format(arg1, arg2, kwarg1))

这篇关于在装饰器中解析args和kwargs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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