2012-09-06 10 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 

これはただで遊ぶために小さなサンプルです。

2

I本当にデコレータ構文のように、それは例えば

コードユーバーが明示的になるために、Djangoでこのlogin_requiredデコレータがあります:https://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

が関数/ビューのための@login_required行動を注入するために、あなたが得たすべてのデコレータを添付してください(if:... else:...どこにでも式を制御するなど)

PEPを読んでください!

http://www.python.org/dev/peps/pep-0318/

それが行われた言語の決定にlosta歴史を持ち、そしてなぜ

関連する問題