2012-09-06 27 views
9

可能重複:
Understanding Python decoratorsPython裝飾只是語法糖?

我很新的使用Python裝飾,從我對我的第一印象明白,他們只是語法糖。

更復雜的用途是否有更深刻的用途?

+2

這裏有一個全面的答案與使用示例在這裏http://stackoverflow.com/questions/739654/understanding-python-decorators#answer-1594484 –

+0

謝謝。這真的很有用,我不知道如何關閉或刪除這篇文章。如果有人能做到這一點,那就太好了。 – coredump

+0

這裏是一個小教程,所以你可以看到他們是什麼:https://www.codementor.io/python/tutorial/introduction-to-decorators – Sheena

回答

10

是的,它是語法糖。一切都可以在沒有它們的情況下實現,但需要更多的代碼。但它可以幫助您編寫更簡潔的代碼。

實例:

from functools import wraps 

def requires_foo(func): 
    @wraps(func) 
    def wrapped(self, *args, **kwargs): 
     if not hasattr(self, 'foo') or not self.foo is True: 
      raise Exception('You must have foo and be True!!') 
     return func(self, *args, **kwargs) 
    return wrapped 

def requires_bar(func): 
    @wraps(func) 
    def wrapped(self, *args, **kwargs): 
     if not hasattr(self, 'bar') or not self.bar is True: 
      raise Exception('You must have bar and be True!!') 
     return func(self, *args, **kwargs) 
    return wrapped 

class FooBar(object): 

    @requires_foo     # Make sure the requirement is met. 
    def do_something_to_foo(self): 
     pass 

我們也鏈/堆疊在彼此的頂部上的裝飾。

class FooBar(object): 
    @requires_bar 
    @requires_foo     # You can chain as many decorators as you want 
    def do_something_to_foo_and_bar(self): 
     pass 

好的,我們最終可能會有很多很多裝飾器在彼此之上。

我知道!我會寫一個應用其他裝飾器的裝飾器。

因此,我們可以這樣做:

def enforce(requirements): 
    def wrapper(func): 
     @wraps(func) 
     def wrapped(self, *args, **kwargs): 
      return func(self, *args, **kwargs) 
     while requirements: 
      func = requirements.pop()(func) 
     return wrapped 
    return wrapper 

class FooBar(object): 
    @enforce([reguires_foo, requires_bar]) 
    def do_something_to_foo_and_bar(self): 
     pass 

這是一個小樣本只是一起玩。