Kashirigi
5 years ago
4 changed files with 139 additions and 62 deletions
@ -1,29 +0,0 @@ |
|||||||
def deco(func): |
|
||||||
def wrapper(*args, **kwargs): |
|
||||||
func(*args, **kwargs) |
|
||||||
wrapper.count+=1 |
|
||||||
wrapper.count=0 |
|
||||||
return wrapper |
|
||||||
|
|
||||||
def deco2(func): |
|
||||||
def wrapper(*args, **kwargs): |
|
||||||
print(args) |
|
||||||
def fname(*args): |
|
||||||
print('args',args) |
|
||||||
|
|
||||||
return fname |
|
||||||
|
|
||||||
@deco2 |
|
||||||
def fname(arg): |
|
||||||
print(arg) |
|
||||||
|
|
||||||
|
|
||||||
@deco |
|
||||||
def main(arg): |
|
||||||
print(arg) |
|
||||||
|
|
||||||
for item in range(3): |
|
||||||
main(item) |
|
||||||
print('count', main.count) |
|
||||||
|
|
||||||
fname('test') |
|
@ -0,0 +1,123 @@ |
|||||||
|
#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() |
@ -1,31 +0,0 @@ |
|||||||
#import numpy as np |
|
||||||
#import time |
|
||||||
import math |
|
||||||
from math import tan as qe |
|
||||||
|
|
||||||
def deco(func): |
|
||||||
def wrapper(y): |
|
||||||
ang = y *2 *math.pi/360 |
|
||||||
return func(ang) |
|
||||||
return wrapper #You need two returns! So confusing! |
|
||||||
|
|
||||||
|
|
||||||
def test(number): |
|
||||||
return number |
|
||||||
|
|
||||||
@deco |
|
||||||
def test2(number): |
|
||||||
return number |
|
||||||
|
|
||||||
|
|
||||||
print('undecorated') |
|
||||||
print(test(45)) |
|
||||||
print('decorated') |
|
||||||
print(test2(45)) |
|
||||||
print('math.tan') |
|
||||||
print(qe(45)) |
|
||||||
print('math.tan decorated') |
|
||||||
test3=deco(qe) |
|
||||||
print(type(test3)) |
|
||||||
print(test3(45)) |
|
||||||
print(math.tan(45)) |
|
Loading…
Reference in new issue