Kashirigi
5 years ago
4 changed files with 139 additions and 62 deletions
@ -1,29 +0,0 @@
@@ -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 @@
@@ -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 @@
@@ -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