2017-06-06 4 views
0

この質問は、How pass unknown list of unnamed arguments to a python decorator?の重複ではありません。私はここで異なるが、関連する質問をしています。なぜ名前付き引数のリストをこのデコレータに渡すことができますか?

以下に示すように、私はPythonデコレータmy_decoratorメソッドを作成しました。私は、このデコレータは、引数の未知のリストを受け入れるようにしたい:

#!/usr/bin/env python 
from functools import wraps 

class A: 
    def my_decorator(self, func=None, *args, **kwargs): 
     print "Hello World2!" 
     print 'args = {}'.format(args) 
     print 'kwargs = {}'.format(kwargs) 
     def inner_function(decorated_function): 
      def wrapped_func(*fargs, **fkwargs): 
       print "Hello World3!" 
       return decorated_function(*fargs, **fkwargs) 
      return wrapped_func 

     if func: 
      return inner_function(func) 
     else: 
      return inner_function 

class B: 
    my_a = A() 

    @my_a.my_decorator(a1="Yolo", b1="Bolo") 
    def my_func(self): 
     print "Hello World1!" 

my_B = B() 
my_B.my_func() 

このコードは完全に正常に動作します:

Hello World2! 
args =() 
kwargs = {'a1': 'Yolo', 'b1': 'Bolo'} 
Hello World3! 
Hello World1! 

しかし、今、その代わり@my_a.my_decoratorに名前付き引数を渡すので、私は無名の引数を渡したいですこのような:@my_a.my_decorator('Yolo', 'Bolo')、それは失敗します。

Hello World2! 
args = ('Bolo',) 
kwargs = {} 
Hello World3! 
Traceback (most recent call last): 
    File "./decorator_test.py", line 20, in <module> 
    class B: 
    File "./decorator_test.py", line 23, in B 
    @my_a.my_decorator('Yolo', 'Bolo') 
    File "./decorator_test.py", line 12, in wrapped_func 
    return decorated_function(*fargs, **fkwargs) 
TypeError: 'str' object is not callable 

私はこれをどのように修正することができますか?

+5

'' Yolo''を 'func'引数として渡しています。 – user2357112

+1

これはデコレータとは関係ありません。すべての関数がこのように動作します。基本的に、キーワード引数を使用している場合は、名前を使用して渡すことも、位置を使って渡すこともできます。 [* keyword only argument *](https://www.python.org/dev/peps/pep-3102/)が必要です。あなたの署名は次のようにする必要があります: 'def my_decorator(self、* args、func = None、* * kwargs) ' –

+1

そのデコレータはなぜメソッドですか?それは何にも "自己"を使用しません。 – jonrsharpe

答えて

1
def my_decorator(self, *args, **kwargs): 
    [skip] 
    if 'func' in kwargs: 
     return inner_function(kwargs.pop('func')) 
    else: 
     return inner_function 
関連する問題