|
| 1 | +# what is decorator? |
| 2 | +# A decorator is a design pattern in Python that allows a user to add new functionality to an existing object without modifying its structure. Decorators are usually called before the definition of a function you want to decorate. |
| 3 | +# Decorators are very powerful and useful tool in Python since it allows programmers to modify the behavior of function or class. Decorators allow us to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying it. |
| 4 | +# In Decorators, functions are taken as the argument into another function and then called inside the wrapper function. |
| 5 | + |
| 6 | +# methods and functions are really the same. The only difference is that methods expect that their first argument is a reference to the current object (self). |
| 7 | +# https://stackoverflow.com/questions/739654/how-do-i-make-function-decorators-and-chain-them-together |
| 8 | + |
| 9 | + |
| 10 | +def method_friendly_decorator(method_to_decorate): |
| 11 | + def wrapper(self, lie): |
| 12 | + lie = lie - 3 # very friendly, decrease age even more :-) |
| 13 | + return method_to_decorate(self, lie) |
| 14 | + |
| 15 | + return wrapper |
| 16 | + |
| 17 | + |
| 18 | +class Lucy(object): |
| 19 | + |
| 20 | + def __init__(self): |
| 21 | + self.age = 32 |
| 22 | + |
| 23 | + @method_friendly_decorator |
| 24 | + def sayYourAge(self, lie): |
| 25 | + print("I am {0}, what did you think?".format(self.age + lie)) |
| 26 | + |
| 27 | + |
| 28 | +l = Lucy() |
| 29 | +l.sayYourAge(-3) |
| 30 | + |
| 31 | + |
| 32 | +def a_decorator_passing_arbitrary_arguments(function_to_decorate): |
| 33 | + # The wrapper accepts any arguments |
| 34 | + def a_wrapper_accepting_arbitrary_arguments(*args, **kwargs): |
| 35 | + print("Do I have args?:") |
| 36 | + print(args) |
| 37 | + print(kwargs) |
| 38 | + # Then you unpack the arguments, here *args, **kwargs |
| 39 | + # If you are not familiar with unpacking, check: |
| 40 | + # http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ |
| 41 | + function_to_decorate(*args, **kwargs) |
| 42 | + |
| 43 | + return a_wrapper_accepting_arbitrary_arguments |
| 44 | + |
| 45 | + |
| 46 | +@a_decorator_passing_arbitrary_arguments |
| 47 | +def function_with_named_arguments(a, b, c, platypus="Why not ?"): |
| 48 | + print("Do {0}, {1} and {2} like platypus? {3}".format(a, b, c, platypus)) |
| 49 | + |
| 50 | + |
| 51 | +function_with_named_arguments("Bill", "Linus", "Steve", platypus="Indeed!") |
| 52 | +# outputs |
| 53 | +# Do I have args ? : |
| 54 | +# ('Bill', 'Linus', 'Steve') |
| 55 | +# {'platypus': 'Indeed!'} |
| 56 | +# Do Bill, Linus and Steve like platypus? Indeed! |
| 57 | + |
| 58 | + |
| 59 | +class Mary(object): |
| 60 | + |
| 61 | + def __init__(self): |
| 62 | + self.age = 31 |
| 63 | + |
| 64 | + @a_decorator_passing_arbitrary_arguments |
| 65 | + def sayYourAge(self, lie=-3): # You can now add a default value |
| 66 | + print("I am {0}, what did you think?".format(self.age + lie)) |
| 67 | + |
| 68 | + |
| 69 | +m = Mary() |
| 70 | +m.sayYourAge() |
0 commit comments