2011-12-14 21 views
3

私が提供したデコレータパターンに関するセッションには、提供されているほとんどの例がjava.Toにありました。例の下の例では、ピザオブジェクトは2つのトッピングで装飾されています。私はここで私はmakePizza機能は2つの機能で飾られていることがわかりますが、それは多くのことを異なりますが、このpythonデコレータはデコレータパターンを厳密に実装していますか?

@applyTopping2 
@applyTopping1 
makePizza(): 
    pass 

のようなシナリオで使用されているデコレータを見てきたPythonで

Pizza vegPizza = new ToppingsType1(new ToppingType2(new Pizza())) 

javaのクラスベースのアプローチから。 私の質問は、pythonデコレータは厳密にデコレータパターンを実装するのか、または実装は少し異なりますが、アイデアは同じです。

PS:私はデコレータの標準的な定義を検索する場所を確認していないpattern.thoughウィキペディアあなたは動的言語(JS)に例を示しますが、私の質問はまだ良い:)

+0

Pythonデコレータもクラスになることはありません。 – jsbueno

+1

*デコレータパターン*を厳密に実装していますか?デコレータの外観は標準的な定義がありますか? – Constantinius

+2

「厳格なデコレータパターン」が何であるかの定義を得ることには、あなたの負担があると思います。 (そして、Pythonのファンは厳密性が無関係で、Pythonのアプローチを守る理由を説明することができます:-)) – jsbueno

答えて

2

を保持すべきread this説明していますPythonのデコレータは何ですか?

私たちがPythonについて懸念している「デコレータ」は、DecoratorPattern [...]とまったく同じものではありません。 Pythonのデコレータは、Pythonの構文を変更したもので、関数やメソッド(将来のバージョンのクラスなど)をより便利に変更することができます。これにより、DecoratorPatternのより読みやすいアプリケーションだけでなく、他の用途もサポートされます。

こうして、 "古典的な"デコレータパターンをPythonのデコレータで実装することができますが、それらのデコレータでもっと多くの(面白い)ことができるようになります。あなたのケースでは

、それはできるようになっています

def applyTopping1(functor): 
    def wrapped(): 
     base_pizza = functor() 
     base_pizza.add("mozzarella") 
     return base_pizza 
    return wrapped 

def applyTopping2(functor): 
    def wrapped(): 
     base_pizza = functor() 
     base_pizza.add("ham") 
     return base_pizza 
    return wrapped 

そしてあなたはマルゲリータを取得します:)

1

ない本当の答え、1はPythonで物事を行うことができますどのように上だけで楽しい一例 - 静的言語に比べ:

def pizza_topping_decorator_factory(topping): 
    def fresh_topping_decorator(pizza_function): 
     def pizza_with_extra_topping(*args, **kw): 
      return pizza_function(*args, **kw) + ", " + topping 
     return pizza_with_extra_topping 
    return fresh_topping_decorator 


mozzarela = pizza_topping_decorator_factory("mozarella") 
anchove = pizza_topping_decorator_factory("anchove") 

@anchove 
@mozzarela 
def pizza(): 
    return "Pizza" 

Pythonのコンソール上でこのコード貼り付け:

>>> 
>>> print pizza() 
Pizza, mozarella, anchove 
+0

可読性を向上させるために、実際のコードで '_decorator_factory'接尾辞を使用しない方が良いです。 – lig

+0

@lig - shure - ここのほとんどの名前は、上記のコードの一部です。 – jsbueno

1

Pythonの@decoratorの構文は、構文砂糖にすぎません。

コード

@decorator 
def foo(): 
    pass 

def foo(): 
    pass 

foo = decorator(foo) 

以外の何ものでもありません最終的な結果は、ちょうどそれがあるためにあなたが望む何をすべきかに依存します。

クラスをdecoratorとして使用し、foo__init__ argでこのクラスからインスタンス化されたオブジェクトを取得できます。

あなたはこれがあなたのコードがどのように見えるか、それがJavaの世界から、任意のパターンまたは誰かではなく何をするかを決定する人だけである

class Decorator(object): 
    def __init__(self, arg1, arg2): 
     pass 

    def __call__(self, foo): 
     return foo() 

@Decorator(arg1_value, arg2_value) 
def foo(): 
    pass 

怒鳴るコードに似デコレータなど、いくつかのパラメータを指定してインスタンス化されたオブジェクトを使用することができます:)

+0

"class"キーワードがPythonの "syntax sugar"にすぎない場合、このロジックに従うと、 'Decorator = type(" Decorator "、(object、)、dict(__ init __ = lambda s、foo:setattr(s、 "f"、foo)、__call __ = lambda s:sf())) ' – jsbueno

+0

しかし、関数の場合と同様に、呼び出された関数のオブジェクトを取得します –

関連する問題