2017-06-06 40 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

这与装饰器无关......所有功能都以这种方式工作。实质上,如果您有关键字参数,则可以使用名称或位置来传递它。你需要一个[*关键字唯一参数*](https://www.python.org/dev/peps/pep-3102/)。你的签名应该是:'def my_decorator(self,* args,func = None,* * kwargs)' –

+1

为什么装饰者甚至是一种方法?它从不使用'self'做任何事情。 – jonrsharpe

回答

1
def my_decorator(self, *args, **kwargs): 
    [skip] 
    if 'func' in kwargs: 
     return inner_function(kwargs.pop('func')) 
    else: 
     return inner_function 
相关问题