2014-01-10 117 views
0

我有一個類,讓所謂的WindCMD,它與裝飾功能如何獲得函數的裝飾器?

@options( 
      [ 
       make_option('-s', '--windspeed', 
          default = 999, 
          help = "Set the wind speed." 
          ), 

       make_option('-d', '--winddir', 
          default = 999, 
          help = "Set the wind direction." 
          )        
       ] 
      )  
def do_set_wind_manually(self, line, opts = None): 

有一種可能性,通過使用__dict__獲得類的所有功能,但我怎麼能得到的功能裝飾和選擇?

回答

2

你不能一般。裝飾器只是對函數執行預處理步驟。裝飾器返回的對象可能不是你定義的原始函數(並且在大多數情況下,它包裝了一個它不是的函數)。一旦一個裝飾器完成了它的工作,在返回的函數中就沒有記錄留下的記錄,這是記錄在其他函數上的裝飾器的結果。你可能定義一個裝飾器,它在函數上設置一些屬性。例如:

class options(object): 
    def __init__(self, somearg): 
     self.somearg = somearg 

    def __call__(self, func): 
     func.options = self 
     return func 

>>> @options('foo') 
... def myfunc(): pass 
... 
>>> myfunc.options 
... <__main__.options at 0x19f6d90> 
>>> myfunc.options.somearg 
... 'foo' 

我想如果你真的需要你,也可以寫一個裝飾器來包裝裝飾器並記錄它們。這只是一個粗略的實現,它的想法:

class record_decorator(object): 
    def __init__(self, decorator): 
     self.decorator = decorator 

    def __call__(self, func): 
     result = self.decorator(func) 
     if not hasattr(result, 'decorators'): 
      if hasattr(func, 'decorators'): 
       result.decorators = func.decorators[:] # copy 
      else: 
       result.decorators = [] 
     result.decorators.append(self.decorator) 
     return result 

>>> def a(func): 
...  print 'decorating with a' 
...  return func 
... 
>>> def a(func): 
...  print 'decorating with a' 
...  return func 
... 
>>> @record_decorator(b) 
... @record_decorator(a) 
... def myfunc(): pass 
... 
decorating with a 
decorating with b 
>>> myfunc.decorators 
[<function __main__.a>, <function __main__.b>] 

現在myfunc.decorators包含適用於功能,他們應用的順序所有裝飾的列表。至少在原則上 - 它仍然不會告訴你任何使用而沒有的裝飾者使用record_decorator