1

ジェネリック関数を作成し、他のすべての関数をそれで装飾することに興味があります。新しい関数には、両方の関数からの引数が含まれます。例

def decorator(func):
    Some chunk of code

@decorator
def func(a,b):
    print a**2,b**2
    return a**2,b**2

#Equivalent func of what I want out of the decorator
def equiv_func(a,b,var):
    print var # I want to modify all decorated functions to accept a new
              # argument and print it using "print var"
    print a**2, b**2
    return a**2, b**2

これは私が思いついたものですが...

def decor(func):
    def modify(var,**kwargs):
       print var
       x,y=func(**kwargs)
       return x,y
    return modify

@decor
def func(a,b):
    print a**2,b**2
    return a**2,b**2

>>> func(var="hi",a=4,b=5)
hi
16 25

func の引数を説明する方法として **kwargs を使用しましたが、これは func(a=4,b=5,var の代わりに func(var="hi",a=4,b=5) を使用することを強制します="hi") **kwargs の配置によるものです。

また、この回避策により、関数への引数の入力に既に使用されているため、必要なときにデコレーターを定義するときに **kwargs を使用できなくなります。例

def test(**kwargs):
    if 'test_ans' in kwargs:
        if kwargs['test_ans']=='y':
            return True
    else:
        return False

def decor(func):
    def modify(var,**kwargs):
       if test(**kwargs): # I need to use **kwargs here, but I also need it to define my  
                          # arguments in func.
           print var
       x,y=func(**kwargs)
       return x,y
    return modify

...
# The following is what I expect but due to **kwargs being used for two purposes, 
# it doesn't work
>>>func(var='hi',a=4,b=5,test_ans='y')
'hi'
16 25
>>>func(var='hi',a=4,b=5,test_ans='n')
16 25

私の質問が明確であることを願っています。例は、私が直面している制約を説明するためのものです。それらは実際のコードではありません (たとえば、**kwargs を使用するテスト関数は作成しません)。事前に助けてくれてありがとう、コーディングの達人!

編集:または簡単に言えば、デコレータで kwargs を使用せずに func(a,b) を func(a,b,c,d,e,...,**kwargs) に変更する他の方法はありますか?

4

2 に答える 2

2

funcで呼び出されることを許可できます

func(a=4, b=5, var="hi") 

varキーワード引数を作成します。

def decor(func):
    def modify(*args, **kwargs):
        var = kwargs.pop('var', None)
        print var
        x,y=func(*args, **kwargs)
        return x,y
    return modify

@decor
def func(a,b):
    print a**2,b**2
    return a**2,b**2

func(a=4, b=5, var="hi")
func(a=4, b=5)
于 2013-09-11T02:20:34.770 に答える
2

これを試して。を使用して、関数が受け入れるパラメーターにアクセスできますfunc.func_code.co_varnames。それがわかれば、他のすべてを除外できます。

myfunc編集:これは、パラメーターとして受け入れられた場合、これを効果的に使用できないという点で制限されて**kwargsいます。

def print_decorator(func):
    def wrapped(*args, **kwargs):
        # a tuple of the names of the parameters that func accepts
        func_params = func.func_code.co_varnames
        # grab all of the kwargs that are not accepted by func
        extra = set(kwargs.keys()) - set(func_params)

        for kw in extra:
            print kwargs.pop(kw)

        return func(*args, **kwargs)

    return wrapped

@print_decorator
def myfunc(a, b, c=None):
    print 'myfunc was passed: a={}, b={}, c={}'.format(a, b, c)
    return a, b, c

>>> myfunc(1, b=2, c=3, d=4, e=5)
4
5
myfunc was passed: a=1, b=2, c=3
于 2013-09-11T03:11:59.250 に答える