Decorators: reference
def f():
def g():
print("Hi, it's me 'g'") # 3
print("Thanks for calling me") # 4
print("This is the function 'f'") # 1
print("I am calling 'g' now:") # 2
g()
f()
This is the function 'f'
I am calling 'g' now:
Hi, it's me 'g'
Thanks for calling me
succ(10)
11
successor == succ
True
del succ
실행순서: $f() -> g()$
successor
<function __main__.succ(x)>
def temperature(t):
def celsius2fahrenheit(x):
return 9 * x / 5 + 32
result = "It's " + str(celsius2fahrenheit(t)) + " degrees!"
return result
print(temperature(20))
It's 68.0 degrees!
def g():
print("Hi, it's me 'g'")
print("Thanks for calling me")
def f(func):
print("Hi, it's me 'f'")
print("I will call 'func' now")
func()
f(g)
Hi, it's me 'f'
I will call 'func' now
Hi, it's me 'g'
Thanks for calling me
import math
def foo(func):
print("The function " + func.__name__ + " was passed to foo")
res = 0
for x in [1, 2, 2.5]:
res += func(x)
return res
print(foo(math.sin))
print(foo(math.cos))
The function sin was passed to foo
2.3492405557375347
The function cos was passed to foo
-0.6769881462259364
def f(x):
def g(y):
return y + x + 3
return g
nf1 = f(1)
nf2 = f(3)
print(nf1)
print(nf2)
<function f.<locals>.g at 0x10478d268>
<function f.<locals>.g at 0x1044708c8>
print(nf1(1))
print(nf2(1))
5
7
Decorator 예제
def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
func(x)
print("After calling " + func.__name__)
return function_wrapper
def foo(x):
print("Hi, foo has been called with " + str(x))
return str(x)
print("We call foo before decoration:")
foo("Hi")
print("We now decorate foo with f:")
foo = our_decorator(foo)
print("We call foo after decoration:")
foo(42)
We call foo before decoration:
Hi, foo has been called with Hi
We now decorate foo with f:
We call foo after decoration:
Before calling foo
Hi, foo has been called with 42
After calling foo
foo
이라는 함수는
@our_decorator
함수의 입력을 받아 새로운(꾸며진) 함수 foo
를 반환하게 된다.def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
func(x)
print("After calling " + func.__name__)
return function_wrapper
@our_decorator
def foo(x):
print("Hi, foo has been called with " + str(x))
foo("Hi")
Before calling foo
Hi, foo has been called with Hi
After calling foo
def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
res = func(x)
print(res)
print("After calling " + func.__name__)
return function_wrapper
@our_decorator
def succ(n):
return n + 1
succ(10)
Before calling succ
11
After calling succ
from math import sin
def our_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
res = func(x)
print(res)
print("After calling " + func.__name__)
return function_wrapper
sin = our_decorator(sin)
sin(3.1415)
Before calling sin
9.265358966049024e-05
After calling sin
def argument_test_natural_number(f):
def helper(x):
if type(x) == int and x > 0:
return f(x)
else:
raise Exception("Argument is not an integer")
return helper
@argument_test_natural_number
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
factorial(3)
6
def call_counter(func):
def helper(x):
helper.calls += 1
return func(x)
helper.calls = 0
return helper
@call_counter
def succ(x):
return x + 1
print(succ.calls)
for i in range(10):
succ(i)
print(succ.calls)
0
10
class
활용한 decorate
__call__
: instance를 다시 함수로 선언해주는 역할을 해준다class A:
def __init__(self):
print("An instance of A was initialized")
def __call__(self, *args, **kwargs):
print("Arguments are:", kwargs,args )
x = A()
print("now calling the instance:")
x(3, 4, 5 , x=11, y=10)
print("Let's call it again:")
x(3, 4, x=11, y=10)
An instance of A was initialized
now calling the instance:
Arguments are: {'x': 11, 'y': 10} (3, 4, 5)
Let's call it again:
Arguments are: {'x': 11, 'y': 10} (3, 4)
class Fibonacci:
def __init__(self):
self.cache = {}
tmp = Fibonacci()
tmp.cache
{}
def decorator1(f):
def helper():
print("Decorating", f.__name__)
f()
return helper
@decorator1
def foo():
print("inside foo()")
foo()
Decorating foo
inside foo()
class decorator2:
def __init__(self, f):
self.f = f
def __call__(self):
print("Decorating", self.f.__name__)
self.f() # "inside foo()"
@decorator2
def foo():
print("inside foo()")
foo()
Decorating foo
inside foo()
Reference
https://www.python-course.eu/python3_decorators.php