I want to achieve the decorator design pattern in python using the @ syntax, my code:
class Sandwich():
height = 5
width = 8
def ingredients(self):
print("I have bread")
class Cheese_decorator():
def __init__(self,obj):
self.obj = obj
#something else here so the object becomes the same as the passed one except for the methods to decorate below
#decorated method
def ingredients(self):
self.obj.ingredients()
print("I also have cheese")
#any other method to decorate here
sandwich = Sandwich() # this sandwich wont be decorated
cheese_sandwich = Cheese_decorator(Sandwich()) # this sandwich is decorated
sandwich.ingredients() # prints I have bread
cheese_sandwich.ingredients() # prints I have bread I also have cheese
is there anything I can do like:
sandwich = Sandwich()
cheese_sandwich = @Cheese_decorator
sandwich
? I want to have the decorated object as a var
Regardless of whatever theoretical text you got to read "decorator pattern" - that is not what decorators are in Python.
The @
syntax is meant to transform either a function or a class - and usually, the result is callable itself. If a class is decorated, the result is the class modified (or a new class), that will create instances, not instances themselves, like in your example.
Moreover, as it is applicable either on a def
or on a class
block, the resulting name for the decorated object is the name given in the statement. (Either the name after def
or after the class
keyword). It also implies the @
syntax composes with one statement, and therefore is not an "expression" - and therefore invalid on the right side of an assignment, or other arbitrary places: the @decorator
syntax requires it to be in a line by itself.
That said, your code example, using the the cheese_sandwich = Cheese_decorator(Sandwich())
as it is, conforms with the "decorator pattern" from text books, and you may call it so. It just won't work with the "decorator syntax" from Python.