2011-11-30 9 views
21

"Pythonデコレータ"と "デコレータパターン"の違いは何ですか?Pythonデコレータとデコレータパターンの違いは何ですか?

私はいつPythonデコレータを使うべきですか?デコレータパターンはいつ使うべきですか?

私はPythonデコレータとデコレータパターンの例を探していますか?


@AcceptedAnswer
私はJakob Bowyer's answerが有効であることを知っています。それでも私が理由を理解できるStrikarの答えです。


Srikarさんの答えとリソースを勉強した後、私はこの例を書いたので、私はPythonデコレータとDecoratorパターンを視覚化して理解することができます。

私はStrikarのでを同意しなければならない「Pythonのデコレータは、Decoratorパターンの実装ではありません」。私が学んだことの後で私は、Pythonデコレータがデコレータパターンの実装であると強く確信しています。ちょうど古典的な方法ではありません。

または、私がStrikarはあなたが簡単に実行時でPytohonデコレータを使用することができますPythonのデコレータは、定義時で関数やメソッドに機能を追加する」と述べたという事実にもかかわらず、ことを追加する必要があります。しかし

受け入れて、それは私がPythonのでDecoratorパターンのImplementationを理解して助けたので、私はまだ、Stikerの答えをマーク。

""" 
Testing Python decorators against Decorator Pattern 
""" 
def function(string): 
    return string 

def decorator(wrapped): 
    def wrap(string): 
     # assume that this is something useful 
     return wrapped(string.upper()) 
    return wrap 

def method_decorator(wrapped): 
    def wrap(instance, string): 
     # assume that this is something useful 
     return wrapped(instance, string.upper()) 
    return wrap 

@decorator 
def decorated_function(string): 
    print('! '.join(string.split(' '))) 

class Class(object): 
    def __init__(self): 
     pass 
    def something_useful(self, string): 
     return string 

class Decorator(object): 
    def __init__(self, wrapped): 
     self.wrapped = wrapped 
    def something_useful(self, string): 
     string = '! '.join(string.split(' ')) 
     return self.wrapped().something_useful(string) 

    @method_decorator 
    def decorated_and_useful(self,string): 
     return self.something_useful(string) 


if __name__ == '__main__': 
    string = 'Lorem ipsum dolor sit amet.' 
    print(function(string))     # plain functioon 
    print(decorator(function)(string))  # Python decorator at run time 
    print(decorated_function(string))  # Python decorator at definition time 
    a = Class() 
    print(a.something_useful(string))  # plain method 
    b = Decorator(Class) 
    print(b.something_useful(string))  # Decorator Pattern 
    print(b.decorated_and_useful(string)) # Python decorator decorated Decorator Pattern 
+1

@スリカールは正しいです。あなたは面白いと思うかもしれない[ここ](http://stackoverflow.com/q/3118929/146792)の別の質問です! – mac

+1

@Srikar、私は受け入れることができません質問に記載された問題を解決しないSnswerを受け入れることはできません。申し訳ありませんが、私の質問の提案された解決法のほとんどは機能しません。 – seler

+0

@seler fair enough。 –

答えて

24

デコレータパターン - オブジェクト指向プログラミングでは、デコレータパターンは、既存のオブジェクトに動作を動的に追加できるようにするデザインパターンです。デコレータ・パターンは、設計時にいくつかの基礎作業が行われていれば、同じクラスの他のインスタンスとは独立して、実行時に特定のオブジェクトの機能を拡張(装飾)するために使用できます。

Pythonのデコレータ - 名前にかかわらず、Pythonデコレータはデコレータパターンの実装ではありません。デコレータ・パターンは、静的型オブジェクト指向プログラミング言語で使用されるデザイン・パターンで、実行時にオブジェクトに機能を追加できるようにします。 Pythonデコレータは、定義時に機能やメソッドに機能を追加するため、デコレータパターンクラスよりも高いレベルの構造です。デコレータパターン自体は、言語がアヒル型であるため、Pythonでは自明に実装可能であるため、通常はそのようには考えられません。したがって、Pythonでは、デコレータは、関数、メソッド、またはクラス定義を変更するために使用される任意の呼び出し可能なPythonオブジェクトです。

私は違いを明確にしたいと思います。あなたが完全に理解していない場合に備えて、これらのリンクを見てください。

How to make a chain of function decorators?

Implementing the decorator pattern in Python

What is the difference between using decorators and extending a sub class by inheritance?

Python Class Decorator

PyWiki - Python Decorators - A detailed discourse

Python Decorators Made Easy

- あなたはそれの終わりに明確よりも出てくるだろう

source1 & source2

+0

編集した質問を見てください。 – seler

0

デコレータデザインのデコレータのアプリケーションです。どちらも、言語の実装とデザインとコンピュータサイエンスのコンセプトについて話しているのと同じことです。

+0

ここをクリックhttp://wiki.python.org/moin/DecoratorPattern – Freelancer

1

違いはこれです:

(a)は、Pythonのデコレータは、既存の方法に関連付けられ、その方法の動作を変更しています。例:

@modifyBehavior 
def original(myString): 
    print myString 

元の動作は上書きされます。これを使用して新しい機能を追加することはできません。

(b)デコレータパターンは多型に関するものです。上のサンプルコードでは、Decorator.something_usefulの動作が上書きされます。元の方法は失われます。本当にデコレータパターンではありません。メソッドを置き換えるのではなく、機能を拡張したり追加したりする必要があります。 a.something_useful(文字列)がb.something_useful(文字列)と同じものを返すようにする必要があります。実際、デコレータパターンでは、通常は元のオブジェクトを置き換えます。ここに私が意味するものは次のとおりです。

class Class(object): 
    def __init__(self): 
     pass 
    def something_useful(self, string): 
     return string 

class Decorator(object): 
    def __init__(self, wrapped): 
     self._wrapped = wrapped 
    def withUnderscores(self, string): 
     return '_'.join(string.split(' ')) 
    def __getattr__(self, name): 
     return getattr(self._wrapped, name) 


if __name__ == '__main__': 
    string = 'Lorem ipsum dolor sit amet.' 
    obj = Class() 
    print('Original: ', obj.something_useful(string)) 
    #This has no underscore function. Use decorator to add. 
    obj = Decorator(obj) 
    print('Replaced spaces: ', obj.withUnderscores(string)) 
    print('Original still works: ', obj.something_useful(string)) 

機能を追加するには、いくつかのデコレータを使用できます。これにより、必要なときに必要なものだけを追加することができます。続きを読む:GoF

関連する問題