Decorator & Visitor Pattern in Python I have implemented Visitor and Decorator Pattern in python. I am much used to java design pattern style and hence thought would try in python as well. Could anyone tell me if this is the correct way to do in Python. 

Is there any better way to do this?

I have made coffee class and decorating it with Sugar and Milk. I have a visitor that will calculate the tax or the cost. The values are random in TaxVisitor and CostVisitor

from abc import ABC, abstractmethod


class Visitable(ABC):

    @abstractmethod
    def accept(self, visitor):
        pass

class CostVisitor(ABC):

    @abstractmethod
    def cost(self, node):
        pass

class TaxVisitor(CostVisitor):

    def cost(self,node):
        if isinstance(node, Milk):
            return 150
        if isinstance(node, Sugar):
            return 100
        if isinstance(node, Plain_Coffee):
            return 10

class CostVisitor(CostVisitor):

    def cost(self,node):
        if isinstance(node, Milk):
            return 15
        if isinstance(node, Sugar):
            return 10
        if isinstance(node, Plain_Coffee):
            return 1

class Coffee(Visitable):

    @abstractmethod
    def cost(self):
        raise ValueError('Implement')

    @abstractmethod
    def display(self):
        raise ValueError('Implement')


class Plain_Coffee(Coffee):

    def cost(self):
        return 2

    def display(self):
        return 'Coffee'

    def accept(self, visitor):
        return visitor.cost(self)


class CoffeeDecorator(Coffee):

    def __init__(self, m_base):
        self.m_base = m_base

    def accept(self, visitor):
        return visitor.cost(self) + self.m_base.accept(visitor)


class Milk(CoffeeDecorator):

    def __init__(self, m_base):
        CoffeeDecorator.__init__(self, m_base)

    def cost(self):
        return self.m_base.cost() + 1

    def display(self):
        return self.m_base.display() + ' milk'

class Sugar(CoffeeDecorator):

    def __init__(self, m_base):
        CoffeeDecorator.__init__(self, m_base)

    def cost(self):
        return self.m_base.cost() + .5

    def display(self):
        return self.m_base.display() + ' sugar'



coffee = Plain_Coffee()
coffee = Milk(coffee)
coffee = Sugar(coffee)

print(coffee.accept(CostVisitor()))

```
In general visitor patterns in other languages are manage with tables, maps or any other struct/object type, here is the improvement that you can make on your code

class TaxVisitor(CostVisitor):

    def cost(self,node):
        if isinstance(node, Milk):
            return 150
        if isinstance(node, Sugar):
            return 100
        if isinstance(node, Plain_Coffee):
            return 10


Can be changed to

class TaxVisitor(CostVisitor):
    self.__table = { "Milk" : 150, "Sugar" : 100, ...}

    def cost(self,node):
        if node.__class__.__name__ in self.__table:
            return self.__table[node.__class__.__name__]


This will make it easy to extender the number of instances by just update the table variable, hope is clear.