initial creation
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
decorama -- demo of 8 combinations of decorator implementation
|
||||
|
||||
decorators applied to functions:
|
||||
1. decorator without args @deco_func
|
||||
decorator returns replacement function
|
||||
2. decorator with args @deco_func(arg, ...)
|
||||
decorator returns wrapper
|
||||
wrapper returns replacement function
|
||||
3. class without args @deco_class
|
||||
__call__ IS replacement function
|
||||
4. class with args @deco_class(arg, ...)
|
||||
__call__ RETURNS replacement function
|
||||
|
||||
#TODO: straighten this mess out
|
||||
decorators applied to classes:
|
||||
(NOTE: replacement class is frequently the original class, but doesn't have to be)
|
||||
5. decorator function without args @deco_func
|
||||
decorator returns replacement class
|
||||
6. decorator function with args @deco_func(arg, ...)
|
||||
decorator returns wrapper
|
||||
wrapper return replacement class
|
||||
7. decorator class without args @deco_class
|
||||
__call__ returns replacement class
|
||||
8. decorator class with args @deco_class(arg, ...)
|
||||
???
|
||||
"""
|
||||
|
||||
from functools import wraps, update_wrapper
|
||||
|
||||
|
||||
def deco_one(wrapped_function):
|
||||
"""
|
||||
function without params decorating a function -- the simplest kind of decorator
|
||||
|
||||
@deco_one
|
||||
def bar():
|
||||
pass
|
||||
|
||||
same as
|
||||
bar = deco_one(bar)
|
||||
|
||||
|
||||
:param wrapped_function: function to decorate
|
||||
:return: replacement function
|
||||
"""
|
||||
@wraps(wrapped_function)
|
||||
def _replacement(*args, **kwargs):
|
||||
print("GREETINGS from deco_one!")
|
||||
result = wrapped_function(*args, **kwargs)
|
||||
return result + 1
|
||||
|
||||
return _replacement
|
||||
|
||||
@deco_one
|
||||
def target_one():
|
||||
print("Hello from target_one")
|
||||
return 1
|
||||
|
||||
print('-' * 60)
|
||||
print("** deco_one() **")
|
||||
print('-' * 60)
|
||||
|
||||
result = target_one()
|
||||
print("target_one() result is:", result)
|
||||
result = target_one()
|
||||
print("target_one() result is:", result)
|
||||
|
||||
print('-' * 60)
|
||||
|
||||
def deco_two(animal):
|
||||
"""
|
||||
function with params decorating a function
|
||||
|
||||
The decorator gets the args, and then returns a wrapper
|
||||
function.
|
||||
|
||||
The wrapper gets the function being wrapped, and returns
|
||||
the replacement function.
|
||||
|
||||
@deco_two('some string')
|
||||
def bar():
|
||||
pass
|
||||
|
||||
same as
|
||||
bar = deco_two('some_string')(bar)
|
||||
or,
|
||||
wrapper = foo('blah')
|
||||
bar = wrapper(bar)
|
||||
|
||||
|
||||
:param value: decorator parameter
|
||||
:return: wrapper function (which returns replacement function)
|
||||
"""
|
||||
|
||||
def wrapper(wrapped_function):
|
||||
|
||||
@wraps(wrapped_function)
|
||||
def _replacement(*args, **kwargs):
|
||||
print(("GREETINGS from deco_two -- animal is {}!".format(animal)))
|
||||
result = wrapped_function(*args, **kwargs)
|
||||
return result
|
||||
|
||||
return _replacement
|
||||
|
||||
return wrapper
|
||||
|
||||
@deco_two('wombat')
|
||||
def target_two_alpha():
|
||||
print("GREETINGS from target_two_alpha")
|
||||
|
||||
@deco_two('coatimundi')
|
||||
def target_two_beta():
|
||||
print("GREETINGS from target_two_beta")
|
||||
|
||||
target_two_alpha()
|
||||
target_two_alpha()
|
||||
target_two_beta()
|
||||
|
||||
class DecoThree():
|
||||
"""
|
||||
class without params decorating a function
|
||||
|
||||
__call__() is the replacement function
|
||||
|
||||
__init__() is passed the wrapped function
|
||||
|
||||
@DecoThree
|
||||
def bar():
|
||||
pass
|
||||
|
||||
same as
|
||||
bar = DecoThree(bar)
|
||||
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, wrapped_function):
|
||||
self.__name__ = wrapped_function.__name__
|
||||
self._wrapped = wrapped_function
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
print("GREETINGS from deco_three!")
|
||||
result = self._wrapped(*args, **kwargs)
|
||||
return result + 3
|
||||
|
||||
|
||||
class DecoFour():
|
||||
"""
|
||||
class with params decorating a function
|
||||
|
||||
__call__() RETURNS the replacement function
|
||||
|
||||
|
||||
@deco_four('blah')
|
||||
def bar():
|
||||
pass
|
||||
|
||||
same as
|
||||
bar = deco_four('blah')(bar)
|
||||
or,
|
||||
wrapper = deco_four('blah')
|
||||
bar = wrapper(bar)
|
||||
"""
|
||||
|
||||
def __init__(self, value):
|
||||
self._value = value
|
||||
|
||||
def __call__(self, wrapped_function):
|
||||
@wraps(wrapped_function)
|
||||
def _replacement(*args, **kwargs):
|
||||
print(("GREETINGS from deco_four -- value is {}!".format(self._value)))
|
||||
result = wrapped_function(*args, **kwargs)
|
||||
return result + 4
|
||||
|
||||
return _replacement
|
||||
|
||||
|
||||
print("Function decorators:")
|
||||
|
||||
|
||||
@deco_one
|
||||
@deco_two('APPLE')
|
||||
@DecoThree
|
||||
@DecoFour('BANANA')
|
||||
def target_function(color, value):
|
||||
"""
|
||||
Target function for decorators 1-4
|
||||
|
||||
:param color: Color as string
|
||||
:param value: Any value
|
||||
:return: None
|
||||
"""
|
||||
print(("Hello from target_function -- color is {} and value is {}".format(color, value)))
|
||||
print(("Target function's name is", target_function.__name__))
|
||||
return 10 * value
|
||||
|
||||
|
||||
TF_RESULT = target_function('red', 10)
|
||||
print(("RESULT is", TF_RESULT))
|
||||
print(('-' * 50))
|
||||
TF_RESULT = target_function('green', 45)
|
||||
print(("RESULT is", TF_RESULT))
|
||||
print(('-' * 50))
|
||||
print()
|
||||
print()
|
||||
|
||||
|
||||
def deco_five(target_class):
|
||||
"""
|
||||
function without params decorating a class
|
||||
|
||||
:param target_class: class to be decorated
|
||||
:return: modified class
|
||||
"""
|
||||
print("GREETINGS from deco_five!")
|
||||
|
||||
@property
|
||||
def _temp(self):
|
||||
return self._value1
|
||||
|
||||
target_class.value_one = _temp
|
||||
|
||||
return target_class
|
||||
|
||||
|
||||
def deco_six(fruit):
|
||||
"""
|
||||
function with params decorating a class; returns wrapper which is applied to target class
|
||||
|
||||
:param fruit:
|
||||
:return: modified class
|
||||
"""
|
||||
print("GREETINGS from deco_six!")
|
||||
|
||||
def wrapper(target_class):
|
||||
target_class._fruit = fruit
|
||||
|
||||
@property
|
||||
def _temp(self):
|
||||
return self._fruit
|
||||
|
||||
target_class.fruit = _temp
|
||||
|
||||
return target_class
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@deco_five
|
||||
@deco_six('MANGO')
|
||||
class TargetClass():
|
||||
|
||||
def __init__(self, v1, v2, v3, v4):
|
||||
self._value1 = v1
|
||||
self._value2 = v2
|
||||
self._value3 = v3
|
||||
self._value4 = v4
|
||||
|
||||
|
||||
T1 = TargetClass('fee', 'fi', 'fo', 'fum')
|
||||
print(("T1 is", T1))
|
||||
print(("value_one:", T1.value_one))
|
||||
|
||||
print(('-' * 50))
|
||||
T2 = TargetClass('eeny', 'meeny', 'miny', 'mo')
|
||||
print(("T2:", T2))
|
||||
print(("T2.value_one:", T2.value_one))
|
||||
print(("T2.fruit:", T2.fruit))
|
||||
|
||||
print(('-' * 50))
|
||||
|
||||
|
||||
class DecoSeven():
|
||||
"""
|
||||
class without params decorating a class
|
||||
|
||||
__new__() returns the modified class (not __init__, because __init__ is *instance* initializer)
|
||||
|
||||
"""
|
||||
|
||||
def __new__(cls, class_): # self is the old class
|
||||
print("GREETINGS from deco_seven!")
|
||||
class_.color = 'blue'
|
||||
return class_
|
||||
|
||||
|
||||
@DecoSeven
|
||||
class TargetClass():
|
||||
pass
|
||||
|
||||
|
||||
T1 = TargetClass()
|
||||
print((T1.color))
|
||||
print(("T1 id:", id(T1)))
|
||||
print((TargetClass.__name__, T1))
|
||||
|
||||
T2 = TargetClass()
|
||||
print((T2.color))
|
||||
print(("T2 id:", id(T2)))
|
||||
|
||||
print(('-' * 50))
|
||||
|
||||
|
||||
class DecoEight():
|
||||
"""
|
||||
class with params decorating a class
|
||||
|
||||
__call__() returns the modified class
|
||||
"""
|
||||
|
||||
def __init__(self, color):
|
||||
print("GREETINGS from deco_eight!")
|
||||
self._color = color
|
||||
|
||||
def __call__(self, old_class):
|
||||
old_class.color = self._color
|
||||
return old_class
|
||||
|
||||
|
||||
@DecoEight('purple')
|
||||
class TargetClass():
|
||||
pass
|
||||
|
||||
T1 = TargetClass()
|
||||
print((T1.color))
|
||||
Reference in New Issue
Block a user