✔️ Nested Function (중첩 함수)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# Nested function
def print1(msg):
def printer():
print(msg)
printer() # call -> print()
# Closure
def print2(msg):
def printer():
print(msg) # 외부에서 정의된 msg를 함수에서 사용
return printer # 내부에서 정의한 함수를 return
print1("Hello1")
ex = print2("Hello2")
ex() # ex()를 call해야 printer()가 실행된다.
|
cs |
✔️ Closure
'폐쇄' 전역 값의 사용을 피할 수 있으며, 데이터를 숨길 수 있다.
Nested 구조를 갖춰야하며
부모 함수의 변수나 정보를 중첩함수가 내부에서 사용해야하며
부모 함수는 중첩 함수를 return 해야 한다.
1
2
3
4
5
6
7
8
9
|
def add_number(num):
def adder(number):
print('adder is a closure')
return num+number
return adder
a_10 = add_number(10)
a = a_10(21)
print(a)
|
cs |
🔳 출력 결과
adder is a closure ⇽ line8
31 ⇽ line9
✔️ Decorator
- 함수를 인자로 받아 새로운 함수를 만들어 반환하는 함수
- 함수 실행 전 특정 동작을 하게 하는 걸 간단하게 할 수 있게 만드는 것
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
def NewDecorator(func):
# @wraps(func)
def NewAdd(*args, **kwargs):
print('Before call')
result = func(*args, **kwargs)
print('After call')
return result
return NewAdd
@NewDecorator # 기본이 되는 함수 형식을 사용하겠다! 는 의미
def add1(a, b):
print('Add1')
return a + b
sum = add1(1, 3) # ‘Before call’ ‘Add’ ‘After call’ 4
print(sum)
print(add1.__name__) # NewAdd
def add2(a, b):
print('Add2')
return a + b
add2 = NewDecorator(add2)
print(add2(1, 3))
|
cs |
🔳 출력 결과
Before call ⇽ line15 - 4
Add1 ⇽ line15 - line5 - 12
After call ⇽ line15 - 6
4 ⇽ line16
NewAdd ⇽ line17
Before call ⇽ line24
Add2 ⇽ line24
After call ⇽ line24
4 ⇽ line24
@decorator 와 add = NewDecorator(add)는 똑같이 decorator 함수를 실행시키는 코드이다
📌 class 에도 Decorator를 사용할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class ClassDecorator(object):
def __init__(self, f):
print('__init__')
self.f = f
def __call__(self, *args, **kwargs):
print('__call__')
return self.f(*args, **kwargs)
@ClassDecorator # 해당 클래스를 Decorator로 쓰고 있다! 는 의미
def Fn(a, b):
print("inside Fn()")
return a + b
print(Fn(1, 2))
|
cs |
🔳 출력 결과
__init__ ⇽ line 14
__call__ ⇽ line 14
inside Fn() ⇽ line 14 - 7 - 11
3 ⇽ line 14
📌 Property decorator
Built-in decorator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class P1:
def __init__(self,x):
self.set_x(x)
def get_x(self):
return self.x
def set_x(self, x):
if x < 0: self.x = 0
elif x > 1000: self.x = 1000
else: self.x = x
p1 = P1(1001); print(p1.get_x()) # 1000
p1 = P1(-1); print(p1.get_x()) # 0
p1 = P1(15); print(p1.get_x()) # 15
# 이런 식으로 set할 때 확인할 수 있는 기능, setter
p1.x = 1001; print(p1.get_x()) # 1001
# set_x가 동작하지 않는다
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class P2:
def __init__(self, x):
self.x = x
@property # getter
def x(self):
return self._x # private member로 값을 저장한다
@x.setter
def x(self, x):
if x < 0:
self._x = 0
elif x > 1000:
self._x = 1000
else:
self._x = x
p2 = P2(1001)
print(p2.x) # 1000
p2.x = -12
print(p2.x) # 0
|
cs |
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
|
class C:
def __init__(self):
self._x = None
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x*2
@x.deleter
def x(self):
del self._x
class C2:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value*2
def delx(self):
del self._x
x = property(getx, setx, delx)
c2 = C2()
c2.x = 10
print(c2.x) # 20
|
cs |
'알고리즘' 카테고리의 다른 글
[Python] TypeError: 'NoneType' object is not subscriptable (0) | 2022.03.21 |
---|