简体   繁体   English

如何将此装饰器更改为Python?

[英]how to change this decorator into Python?

I have gotten a copy of the book "Head First Design Patterns", and started to codify some of their examples in Python. 我已经获得了《 Head First Design Patterns》一书的副本,并开始用Python编写他们的一些示例。 I have came to the example about the Decorator pattern, which I know it should use composition, but the author puts a sort of "inheritance". 我以装饰器模式为例,我知道它应该使用合成,但是作者提出了一种“继承性”。 The excuse was that the decorator was made to "achieve the type matching, but not to used it to inherit behaviour". 借口是使装饰器“实现类型匹配,而不是使用它来继承行为”。 I have a question here, I know that Python is not a typed language so when I the example from the book (which is in Java), I got this: 我在这里有一个问题,我知道Python不是一种类型化的语言,所以当我从书中的示例(使用Java编写)中得到以下信息:

from abc import ABCMeta, abstractmethod

class Beverage:
    __metaClass__=ABCMeta

    def __init__(self):
        self.Description="Beverage desconocida"

    def getDescription(self):
        return self.Description

    @abstractmethod
    def calc(self):
        pass


class CondimentDecorator(Beverage):
    __metaClass__=ABCMeta

    @abstractmethod
    def getDescription(self):
        pass

class Espresso(Beverage):
    def __init__(self):
        self.Description="Espresso"

    def calc(self):
        return 2.5

class Pasado(Beverage):
    def __init__(self):
        self.Description="Roasted coffee"

    def calc(self):
        return 1.5

class Mocha(CondimentDecorator):
    def __init__(self,Beverage):
        self.Beverage=Beverage

    def getDescription(self):
        return self.Beverage.getDescription()+" Mocha "

    def calc(self):
        return 0.5+self.Beverage.calc()

def main():
    Beverage=Espresso()
    print Beverage.getDescription()," cost: ",Beverage.calc()
    Beverage2=Pasado()
    Beverage2=Mocha(Beverage2)
    print Beverage2.getDescription()," cost: ",Beverage2.calc()
    Beverage3=Espresso()
    Beverage3=Mocha(Mocha(Beverage3))
    print Beverage3.getDescription()," cost: ",Beverage3.calc()

I wonder if the class: 我想知道下课是否:

CondimentDecorator(Beverage) 调味品装饰(饮料)

is well done, because as long as Python has no types, I would not need to inherit from Beverage; 做得很好,因为只要Python没有类型,我就不需要从Beverage继承; am I right? 我对吗?

If I change it like: 如果我将其更改为:

CondimentDecorator(), my code works still, but in that case I wonder if its necessary to have it, because it has only one abstract method and that's it. CondimentDecorator(),我的代码仍然可以运行,但是在那种情况下,我想知道是否有必要使用它,因为它只有一个抽象方法,仅此而已。

Do I need to change my code to be more consistent with the Python OOP Programming? 我是否需要更改代码以使其与Python OOP编程更加一致?

Thanks 谢谢

Python has no strict typing and often there is no need in inheritance or abstract classes. Python没有严格的类型,并且通常不需要继承或抽象类。 A Decorator-Class is needed for the decorator pattern, because it should define every method of the decorated class to call the method of the embedded instance. 装饰器模式需要Decorator-Class,因为它应定义装饰类的每个方法以调用嵌入式实例的方法。 If you overwrite all methods, you strictly don't need this decorator class. 如果覆盖所有方法,则严格不需要此装饰器类。 Here is a version without inheritance: 这是一个没有继承的版本:

class Espresso(object):
    description="Espresso"

    def calc(self):
        return 2.5

class Pasado(object):
    description="Roasted coffee"

    def calc(self):
        return 1.5

class Mocha(object):
    def __init__(self, beverage):
        self.beverage = beverage

    @property
    def description(self):
        return self.beverage.description+" Mocha"

    def calc(self):
        return 0.5+self.beverage.calc()

def main():
    beverage = Espresso()
    print beverage.description, " cost: ", beverage.calc()
    beverage2 = Pasado()
    beverage2 = Mocha(beverage2)
    print beverage2.description, " cost: ", beverage2.calc()
    beverage3 = Espresso()
    beverage3 = Mocha(Mocha(beverage3))
    print beverage3.description, " cost: ", beverage3.calc()

if __name__ == '__main__':
    main()

On the other side, Python is a dynamic language, and you could write an dynamic decorator 另一方面,Python是动态语言,您可以编写动态装饰器

class GenericDecorator(object): def init (self, obj): self.obj = obj 类GenericDecorator(object):def init (self,obj):self.obj = obj

    def __getattr__(self, name):
        return getattr(self.obj, name)

class Flavored(GenericDecorator):
    """Flavor is for free"""
    def __init__(self, beverage, flavor):
        GenericDecorator.__init__(self, beverage)
        self.flavor = flavor

    @property
    def description(self):
        return self.flavor + '-' + self.obj.description

def main():
    beverage = Espresso()
    beverage = Flavored(beverage, 'Vanilla')
    print beverage.description, " cost: ", beverage.calc()

if __name__ == '__main__':
    main()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM