我参加了一个关于装饰器模式的会话,其中提供的大多数示例都在java中。例如,在下面的示例中,Pizza对象正在使用两个浇头进行装饰。
Pizza vegPizza = new ToppingsType1(new ToppingType2(new Pizza()))
在python中,我看到装饰器正在这样的场景中使用
@applyTopping2
@applyTopping1
makePizza():
pass
虽然在这里我可以看到makePizza函数正在使用两个函数进行修饰,但它与java的基于类的方法有很大不同。 我的问题是python decorators是否严格实现了decorator模式,或者实现有点不同但想法是一样的。
PS:我不知道在哪里查找装饰器模式的标准定义。虽然维基百科给出了一个动态语言(JS)的例子,但我的问题仍然很好:)
答案 0 :(得分: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
答案 2 :(得分:1)
Python中的@decorator
语法只不过是语法糖。
代码
@decorator
def foo():
pass
只不过是
def foo():
pass
foo = decorator(foo)
最终结果取决于你想要的是什么。
您可以将类用作decorator
,并使用foo
作为__init__
arg从此类实例化对象。
您可以使用一些参数实例化的对象作为装饰器,如下面的代码
class Decorator(object):
def __init__(self, arg1, arg2):
pass
def __call__(self, foo):
return foo()
@Decorator(arg1_value, arg2_value)
def foo():
pass
只有你决定你的代码会是什么样子,以及它不会出现任何模式或者来自java世界的人:)