2017-06-06 25 views
0

这个问题与我刚才问的another question有关。如何将未知的参数列表发送给python装饰器 - 当装饰器是不同类的方法时?

我创建了一个python装饰器,如下所示。我希望这个装饰器接受一个未知的参数列表。但有一个额外的皱纹。该装饰是另一个类的实例方法:

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


class A: 

    def my_decorator(self, func=None, **kwargs): 

     def inner_function(decorated_function): 

      def wrapped_func(*fargs, **fkwargs): 
       print kwargs 
       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(arg_1="Yolo", arg2="Bolo") 
    def my_func(): 
     print "Woo Hoo!" 


my_B = B() 
B.my_func() 

但下面这段代码不起作用:

Traceback (most recent call last): 
    File "./decorator_test.py", line 30, in <module> 
    B.my_func() 
TypeError: unbound method wrapped_func() must be called with B instance as first argument (got nothing instead) 

如何解决呢?

+0

你忘了'@ staticmethod',在这里?因为'my_func()'是'B'的方法,并且需要调用一个对象。它也缺少'self'参数。或者应该是'my_B.my_func()'(在这种情况下,'self'仍然缺失)。 – dhke

+0

我的意思是'my_B.my_func()'。抱歉。我修正了错别字,现在它正在工作。 –

回答

0

这里是我的编码方法你的装饰:

class A: 
    def __init__(self, func=None, **kargs): 
     self.args = func 
     self.kargs = kargs 
    def __call__(self, decorated_function): 
     def wrapper_func(*args, **kargs): 
      print kargs 
      return decorated_function(*args, **kwargs) 
     if self.func: 
      #..do something.. 
      return wrapper_func 
     elif 'xyz' in self.kargs: 
      #...do something else here.. 
      return wrapper_func 
     else: 
      ... 


class B: 
    @A(arg_1="Yolo", arg2="Bolo")    # A(...)(my_func) 
    def my_func(): 
     print "Woo Hoo!" 

这是编码装饰的典型方式。 A类在调用时返回可调用的对象。类A的可调用对象将被自动调用以进行修饰。当调用可调用对象时,其方法__call__被触发,并且其运算符重载方法在执行一些定制后返回包装函数。包装函数是围绕原始函数包装逻辑的函数。