Potentially useful code snippets
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
4.0 KiB

#https://www.datacamp.com/community/tutorials/decorators-python
def basicdeco(func):
'''A basic wrapper that just adds things
'''
def wrapper():
print('Some code inside the wrapper runs here')
return func() #function has to run unless you want to run something like ()()
return wrapper
def deco1(func):
'''A wrapper that reads args and kwargs and does nothing with them
#print('before wrapper 2: runs on definition')
Note that placing things before the wrapper will case them to run before the
decorated function call because they must run to wrap the function
'''
def wrapper(*args, **kwargs):
print("This is decorated and took arguments (args, kwargs)")
print(args, kwargs)
print("but didn't pass them to the wrapped function")
return func()
return wrapper
def deco2(func):
'''A wrapper that reads args and kwargs and passes them to the function
#print('before wrapper 2: runs on definition')
Note that placing things before the wrapper will case them to run before the
decorated function call because they must run to wrap the function
Any positional arguments from the function are passed along with args.
'''
def wrapper(*args, **kwargs):
print("This is decorated and took arguments (args, kwargs)")
print(args, kwargs)
print("but didn't pass them to the wrapped function")
return func(*args, **kwargs)
return wrapper
def deco3(*args, **kwargs):
'''This time it is the *decorator* that takes arguments, then passes them to
the decorated function. You have to write a decorator *within* a decorator
print('whatever') #would also run on wrap
Remember that wrappers can access variables outside their scope, but not
vice versa, so the args and kwargs can filter down.
'''
def insidedeco(func):
print('These are the decorator args, kwargs:', args, kwargs)# prints on wrap
def wrapper(*args1, **kwargs1):
print("This is the decorated nested wrapper")
print("Decorator variables", args, kwargs)
print("Inner wrapper variables", args1, kwargs1)
return func(*args1, **kwargs1)
return wrapper
return insidedeco
def practical_example(func):
'''A function counter wrapper'''
def wrapper(*args, **kwargs):
wrapper.count+=1
return func(*args, **kwargs)
wrapper.count=0 #wrapper must be assigned first! That's why this is at the bottom.
return wrapper
@basicdeco
def testme0():
print('@basic deco test function')
print('Undecorated function takes no arguments')
print(30*'_')
@deco1
def testme1():
print('@deco1 test function')
print(30*'_')
@deco2
def testme2(positional):
print('@deco 2 test function')
print('positional variable', positional)
print(30*'_')
@deco3(deco3var="bollocks")
def testme3(positional, *args, **kwargs):
print('@deco3 test function')
print('positional', positional)
print('args, kwargs from decorated function:', args, kwargs)
print(30*'_')
@practical_example
def countme():
'''see https://stackoverflow.com/questions/44968004/python-decorators-count-function-call
for how the counting variable works
'''
print('I count for something:', countme.count)
print(30*'_')
@practical_example
def second_count():
print('I also count as a separate object', second_count.count)
print(30*'_')
def wo_decorator_syntax():
'''Just to show how it works without syntax'''
print('Manually wrapped')
print(30*'_')
if __name__ == '__main__':
print('__main__ starts running here___')
print(30*'_')
#decorator without shorthand
basicdeco(wo_decorator_syntax)()
#decorators in action
testme0()
testme1(name='PassedVariable')
testme2("myPositionalVariable")
testme3("positionalVar", name=37)
for i in range(10):
countme()
for i in range(5):
second_count()