Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将此装饰程序更改为Python?_Java_Python_Decorator - Fatal编程技术网

Java 如何将此装饰程序更改为Python?

Java 如何将此装饰程序更改为Python?,java,python,decorator,Java,Python,Decorator,我已经得到了一本书的副本Head First Design Patterns,并开始用Python编写它们的一些示例。我来举一个关于Decorator模式的例子,我知道它应该使用composition,但是作者提出了一种继承。理由是装饰器是为了实现类型匹配,而不是用来继承行为。我这里有一个问题,我知道Python不是一种类型化语言,所以当我从《Java》一书中看到这个例子时,我得到了: from abc import ABCMeta, abstractmethod class Beverage

我已经得到了一本书的副本Head First Design Patterns,并开始用Python编写它们的一些示例。我来举一个关于Decorator模式的例子,我知道它应该使用composition,但是作者提出了一种继承。理由是装饰器是为了实现类型匹配,而不是用来继承行为。我这里有一个问题,我知道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()
我想知道班级是否:

调味品

做得很好,因为只要Python没有类型,我就不需要继承Beverage;我说得对吗

如果我改成:

调味品装饰师,我的代码仍然有效,但在这种情况下,我想知道是否有必要拥有它,因为它只有一个抽象方法,就是它

我是否需要更改代码以与Python OOP编程更加一致


感谢

Python没有严格的类型,而且通常不需要继承或抽象类。Decorator模式需要Decorator类,因为它应该定义Decorator类的每个方法来调用嵌入实例的方法。如果覆盖所有方法,则严格来说不需要这个decorator类。以下是一个没有继承的版本:

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()
另一方面,Python是一种动态语言,您可以编写动态装饰器

类GenericDecoratorobject: 定义初始化自身,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()