중첩함수
Nested Function
중첩 함수는 함수로 감싸진 함수를 뜻한다. Nested function
은 개념적인 용어로, 함수 안에 함수는 Inner function
이라고 표현하고, 이 함수를 감싸고 있는 외부 함수를 Outer function
이라고 한다.
이때, 각 내부 함수들은 scope chain
에 의해서 자신을 감싸고 있는 외부 함수의 메모리에 접근이 가능하다. (외부 함수가 가지고 있는 변수나 매개변수 등에 접근할 수 있고 사용할 수 있다는 뜻이다. 정확히는 외부 함수의 메모리를 복사해서 가지고 있다는 의미이다)
First-Class Function
first-class
의 기본은 first-class citizen
이라는 개념이다
프로그래밍 언어에서 first-class citizen
속성을 가진다는 것은 어떤 객체를 다른 객체의 매개변수로 전달하거나, 함수의 반환값으로 사용하거나, 변수에 값으로 할당할 수 있다는 것을 의미한다. 요약하면 객체, 즉 자료형이나 함수등을 그 자체로 매개변수에 전달하거나 반환값으로 사용할 수 있으면 그것은 first-class citizen
속성을 가지고 있다고 할 수 있다.
###############################
# Case 1 : 함수(객체)를 값으로 할당하는 경우
def square(x):
return x*x
square(10)
f = square
print(f(10))
# 100
###############################
# Case 2 : 함수(객체)를 함수(객체)의 매개변수로 넘기는 경우
def square(x):
return x*x
def bind(func, arg_list):
result = []
for arg in arg_list:
result.append(func(arg))
return result
print(bind(square, [2,3,5]))
# [4,9,25]
Closure
Closure
는 중첩함수의 일종이다. 개념 상으로는 Nested function
의 하위 개념이다.
Closure
란 함수가 사용하는 환경을 저장하는 것이다.
# 내부함수를 반환하지만 이때 이 함수와 관련된 환경을 따로 저장하고 있다.
def multiple_of_ten():
square_root = 10 # nonlocal 변수
def square(x):
return square_root ** x
return square
f = multiple_of_ten()
print(f(2))
# 100
Closure 언제 사용하는가?
global
변수를 사용하고 싶지 않을 때 → 그 역할을nonlocal
변수가 대신하여 데이터를 숨길 수 있다- 클래스를 사용하지 않기 위해서 → 클래스는 함수에 비해 크기가 크기 때문에 다루는 변수나 함수가 많지 않은 경우 클래스 사용을 자제한다
decorator
→ 어떤 함수를 실행하기 전이나 실행하고 난 뒤에 특정 기능을 수행하기 위한 기능
Closure 사용시 주의사항
nonlocal
변수들은 외부 함수가 실행되는 시점에서 생성되고 복사되어 내부 함수의 __closure__
속성에 저장된다. 그래서 nonlocal
변수로 시간과 관련된 값을 사용하게 되면 의도하지 않은 결과가 나올 수 있다.
import datetime
import time
def logger():
now = datetime.datetime.now()
def print_log(message):
return f"{now}, {message}"
return print_log
logger = logger()
print(logger("start"))
time.sleep(10)
print(logger("After 10 sec")
기대하는 결과
>> 2020-12-03 15:38:30, start
>> 2020-12-03 15:38:40, After 10 sec.
실제 결과
>> 2020-12-03 15:38:30, start
>> 2020-12-03 15:38:30, After 10 sec.
Decorator
데코레이터는 말 그대로 장식을 하기 위한 문법으로, 기존의 클래스나 함수를 수정하지 않고 기능을 덧붙이는 기능을 한다.
def deco(func):
def wrapper():
print("before")
ret = func()
print("after")
return ret
return wrapper
@deco # deco(base) 와 같은 의미이다.
def base():
print("base func")
base()
# f = deco(base)
# f()
# f() 와 base() 는 같은 결과를 가진다
Decorator 를 활용한 시간차 계산
import time
def measure_run_time(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args)
end = time.time()
print(f"function running time : {end - start}")
return result
return wrapper
@measure_run_time
def worker(delay_time):
time.sleep(delay_time)
return
worker(5)
# 결과값
# function running time : 5.004865884780884
Author And Source
이 문제에 관하여(중첩함수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@happy_sangahn/중첩함수저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)