본문 바로가기
기타

TIL - 22.01.29

by DGK 2022. 1. 29.

 

개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.

 

1월 29일(토)


Closure

1. Nested Function

 

  1. 중첩함수는 함수로 감싸인 함수를 의미한다. (함수 안에 정의된 함수)
  2. Nested function은 개념적인 용어로, 함수 안에 정의된 함수는 Inner function이라고 표현한다.
  3. 그리고 Inner function를 감싸고 있는 외부함수를 Outer function이라고 한다.
  4. 각 내부 함수들은 Scope chain에 의해서 자신을 감싸고 있는 외부함수의 메모리에 접근할 수 있다.
  5. 좀 더 자세히 설명하면, 내부함수는 외부 함수가 가지고 있는 변수나 매개변수 등에 접근할 수 있고 사용할 수 있다는 의미이다.
  6. 이는 내부함수가 외부 함수의 메모리를 복사해서 가지고 있다는 의미이다.

(참고)

def calculator(x,y):
    def add():
        return x+y

    def sub():
        return x-y

    return (add(), sub())

 

2. First-Class Function

 

  1. 파이썬에서 사용하는 여러 기술을 이해하기 위한 가장 기본적인 개념이 바로 'First-Class'이다.
  2. First-Class의 기본은 'first-class citizen'이라는 개념에 있다.
  3. 프로그래밍 언어에서 first-class citizen 속성을 가진다는 것은 어떤 객체를 다른 객체의 매개변수로 전달하거나, 함수의 반환값으로 사용하거나, 변수에 값으로 할당할 수 있다는 것을 의미한다.
  4. 즉, 객체(자료형 및 함수) 등을 그 자체 매개변수로 전달하거나 반환값으로 사용할 수 있으면 이는 first-class citizen 속성을 가진다고 말한다. 

(참고)

def square(x):
    return x*x

f = square     # first-class citizen
f(10)          # first-class function

 

3. Closure

 

  1. Closure는 중첩함수의 일종으로 개념상으로는 Nested function의 하위 개념이다.
  2. 사전적 정의로는 first-class function을 지원하는 언어에서 함수와 유효 범위의 이름을 바인딩하는 기술이다.
    (함수와 함수가 사용하는 환경을 저장하는 것)
  3. 즉, 외부함수의 반환값으로 내부함수를 반환하는 함수라고 정의할 수 있다.
  4. 참고로, 외부함수의 지역변수인 Non-local 변수가 존재하고 외부함수가 이미 종료되었어도 내부함수는 외부함수와 관련된 환경을 따로 저장하고 있기 때문에 Non-local 변수를 참고할 수 있다.
  5. 따라서, 클로저(Closure)는 함수와 함수가 사용하는 환경을 저장하는 개념이다.

(참고)

def multiple_of_ten():
    square_root = 10

    def square(x):
        return square_root ** x

    return square

f = multiple_of_ten()

f(2)
f(3)

 

4. Closure를 사용하는 이유

 

  1. Global 변수를 사용하지 않고, Non-local 변수로 특정 데이터를 숨겨서(보호해서) 함수 기능을 사용하고자 할 때 주로 사용된다.
  2. 다루는 변수나 함수가 많지 않은 경우에는 클래스를 사용하는 것 보다 클로저를 사용하는 것이 더욱 효율적이다.
  3. 데코레이터를 사용할 때 주로 사용된다. (어떤 함수를 실행하기 전이나 실행하고 난 후에 특정 기능을 수행하기 위한 목적)

 

5. Closure 사용 시 주의할 점

 

  1. 클로저에서 외부함수의 변수인 Non-local 변수는 외부함수가 실행되는 시점에서 생성되고 복사되어 내부함수의 __Closure__ 속성에 저장된다.
  2. 이 때문에 클로저 사용 시, Non-local 변수로 시간과 관련된 값을 사용하게 되면 의도하지 않은 결과가 나타날 수 있다.
  3. 아래의 예시코드를 참고하면, 외부함수가 실행되는 시점에 datetime.now() 함수가 실행되고 해당 값이 __Closure__ 속성에 저장되기 때문에 내부함수에는 계속 동일한 시간값만 적용되는 것이다.
  4. 따라서 클로저를 구현할 때에는 Non-local 변수에 시간이나 흐름에 따라 변하는 값을 할당하지 않아야 한다.

(참고)

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:35:30, start
>> 2020-12-03 15:38:40, After 10 sec.


실제 결과 :

>> 2020-12-03 15:38:30.670492, start
>> 2020-12-03 15:38:30.670492, After 10 sec.

'''

 

 

'기타' 카테고리의 다른 글

TIL - 22.01.31  (0) 2022.01.31
TIL - 22.01.30  (0) 2022.01.30
TIL - 22.01.28  (0) 2022.01.29
TIL - 22.01.27  (0) 2022.01.27
TIL - 22.01.26  (0) 2022.01.26

댓글