10

引数と kwargs を受け取る関数があり、次のコードのように、関数の2 番目の引数の値に基づいてデコレータで何かを行う必要があります。

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 では、ユーザーが 2 番目の引数を通常の引数またはキーワード引数として関数を呼び出すことができるため、ユーザーがkwarg として呼び出すmy_funcと、 が発生することです。以下を参照してください。arg2IndexError

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

これを回避する方法はありtry/exceptますIndexErrorか?

4

2 に答える 2

10

decoratorpythonパッケージを使用して答えを見つけました。このパッケージの特徴の 1 つは、ユーザーがどのように渡しても位置/キーワード引数を保持することです。多くのコードを削減できるという追加の利点があるため、元のコードは次のとおりです。

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))
于 2013-09-20T15:25:44.740 に答える