일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- concurrency
- 시바견
- Substring with Concatenation of All Words
- Convert Sorted List to Binary Search Tree
- Python Implementation
- Regular Expression
- DWG
- 파이썬
- 프로그래머스
- Python Code
- LeetCode
- 밴픽
- attribute
- Protocol
- 30. Substring with Concatenation of All Words
- 715. Range Module
- 315. Count of Smaller Numbers After Self
- Decorator
- 109. Convert Sorted List to Binary Search Tree
- 운영체제
- 컴퓨터의 구조
- t1
- Generator
- shiba
- data science
- iterator
- Class
- 43. Multiply Strings
- Python
- kaggle
- Today
- Total
Scribbling
Python: Decorator & Closure 본문
Decorator is a callable that takes another function as its parameter. Decorator is executed during 'import time'.
The key idea about closure you must understand is that it can access to 'nonlocal' variables outside the function.
Take a look at the below exmaple.
def make_averager():
series = []
def averager(new_val):
series.append(new_val)
return sum(series) / len(series)
return averager
avg = make_averager()
avg(10)
avg(11)
print(avg(12))
Binding between freevars and closures are kept until the end.
print(avg.__code__.co_freevars)
print(avg.__closure__)
"Nonlocal" keyword is to define free variable. In the previous example, "series" was automatically interpreted as free variable as it is mutable data type. On the other hand, nonlocal keyword should be used in closure when dealing with immutable data types.
def make_averager():
count = 0
total = 0
def averager(new_val):
nonlocal count, total
count += 1
total += new_val
return total / count
return averager
avg = make_averager()
avg(10)
avg(11)
print(avg(12))
Now, back to decorator. Usually, we call a function in decorator. Below is the typical code format.
import time
import functools
def clock(func):
@functools.wraps(func)
def clocked(*args, **kwargs):
t0 = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - t0
print(f"{func.__name__} took {elapsed:1.3f} seconds and returned {result!r}")
return result
return clocked
@clock
def iamfunc(iamparam:str)->str:
'''
iamfunc
'''
return iamparam + 'was passed'
iamfunc('what happend?')
@functools.wraps(func)
From above, what is this for? This is to maintain original function's properties as below.
print(iamfunc.__name__)
print(iamfunc.__doc__)
Without it, iamfunc.__name__ and iamfunc.__doc__ would have been replaced with clocked function's properties.
import time
def clock(func):
def clocked(*args, **kwargs):
t0 = time.time()
result = func(*args, **kwargs)
elapsed = time.time() - t0
print(f"{func.__name__} took {elapsed:1.3f} seconds and returned {result!r}")
return result
return clocked
Decorators in STL
These three decorators are for class. For details, refer to below link.
@property # for setter / getter method
@classmethod # to define class method
@staticmethod # to define static method
https://focalpoint.tistory.com/283
Python Grammar: Things that I forget often - by Shiba
1. Use deep copy list function copy() can be troublesome when the list has mutable objects. from copy import deepcopy l1 = [1, 2, [3, 4]] l2 = l1.copy() l3 = deepcopy(l1) l1[1] = 3 l1[2][0] = 4 prin..
focalpoint.tistory.com
functools.lru_cache(maxsize, typed) is for memoization.
- if typed is set to True, seperate result will be stored for different data types. (i.e. 1 & 1.0)
- all params should be hashable.
import functools
@functools.lru_cache()
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(30))
Python doesn't provide function overloading. As a result, it feels more complicated to deal with different data types. functools.singleddispath() is to specialize a certain function.
from functools import singledispatch
from collections import abc
import numbers
@singledispatch
def iamfunc(iamparam):
print(f"Not specialized Function Says: {iamparam!r} has data type of {type(iamparam)}.")
@iamfunc.register(str)
def _(string):
print(f"Specialized Function Says: {string!r} has data type of str.")
@iamfunc.register(numbers.Integral)
def _(num):
print(f"Specialized Function Says: {num!r} has data type of int.")
@iamfunc.register(abc.MutableSequence)
@iamfunc.register(tuple)
def _(seq):
print(f"Specialized Function Says: {seq!r} has data type of seq.")
iamfunc([1, 2, 3])
iamfunc((4, 5))
iamfunc(3)
iamfunc(3.3)
iamfunc('hello world')
Notes:
- numbers.Inegral is abstract base class for int type.
- abc.MutableSequence is abstract base class for mutable sequence types.
For multiple decorators, they work like this.
@d1
@d2
def f():
print('f')
f = d1(d2(f))
Now, a little bit more trickier part: decorators with params. Here we call echo as decorator factory.
import functools
def ehco(times):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result * times
return wrapper
return decorator
@ehco(5)
def printer(text):
return text
print(printer('What?'))
print(printer.__name__)
'Computer Science > Python' 카테고리의 다른 글
Python: Pythonic Object (0) | 2022.04.05 |
---|---|
Python: Object References (0) | 2022.04.04 |
Python: Design Patterns (0) | 2022.03.25 |
Python: Memoryview function (0) | 2022.03.23 |
Python Immutable Dictionary, Set (0) | 2022.03.22 |