Python에는 구분하기 애매한 세 가지의 개념이 존재하는데, 바로 IterableSequence, Iterator입니다.

Iterable

Iterable각각의 요소를 하나씩 반환할 수 있는 객체를 말합니다. 이전에 살펴봤던 List와 Tuple, Dictionary와 Set 등이 여기에 속합니다. 정확히는 iterator를 반환하는 빌트인 함수 iter()를 위한 매직 메소드인__iter__()를 구현하고 있는 객체를 iterable이라고 부릅니다.

list, tuple, str은 모두 __iter__()를 구현하고 있으므로 iterable이라고 할 수 있습니다. 해당 객체들 대해 __iter__() 메소드를 호출하니 ***_iterator 객체가 반환되었습니다.

Sequence

Sequence는 __len__()__getitem__() 메소드를 가지고 있는 객체입니다.

따라서, list와 tuple 등 Python의 기본 iterable 타입들은 __iter__(), __len__(), __getitem__() 메소드를 모두 구현하고 있으므로 sequence이자 iterable입니다.

Iterator

Iterator데이터 스트림을 표현합니다. 내부적으로 매직 메소드 __next__()가 구현되어 있어, next()의 인자로 넘겨 다음 데이터를 불러올 수 있다면 iterator라고 말할 수 있습니다.

결론적으로,

  • 빌트인 함수 iter()에 대응되는 매직 메소드 __iter__() 가 정의되어 있는 객체를 Iterable이라고 말할 수 있고
  • 빌트인 함수 len()에 대응되는 매직 메소드 __len__()__getitem__()이 정의되어 있는 객체를 Sequence라고 말하고
  • 빌트인 함수 next()에 대응되는 매직 메소드 __next__()가 정의되어 있는 객체를 Iterator라고 말할 수 있습니다.


'Python 계열 > Python 레거시 글' 카테고리의 다른 글

[Python] Assert  (0) 2018.07.25
[Python] Generator  (0) 2018.07.23
[Python] Decorator  (0) 2018.07.21
[Python] Closure  (0) 2018.07.20
[Python] 문자열의 메모리 할당 방식  (0) 2018.07.19

Python의 함수는 일급 객체라는 특성 상, Decorator라는 문법을 이용해 특정 함수에 미리 만들어 둔 함수를 전달해 기능을 추가할 수도 있습니다. Python 2.4에서 추가되었고, PEP 318에서 확인해볼 수 있습니다. 간단하게, 함수가 호출되기 전에 '함수가 실행됩니다'라는 문자열을 출력해 봅시다.

천천히 살펴봅시다.

  • decorator 함수는 인자로 fn이라는 함수를 받습니다.
  • decorator 함수는 '함수가 실행됩니다.'라는 문자열을 출력하며 fn을 호출하고 그 결과를 반환하는 내부 함수 wrapper를 가지고 있습니다.
  • decorator 함수는 내부 함수인 wrapper를 리턴합니다.

wrapper 함수는 클로저로 인해 decorator 함수가 가진 지역변수 fn에 접근할 수 있게 됩니다. 그럼 코드의 흐름을 살펴 봅시다.

  • decorator 함수에 'hello'라는 문자열을 출력하는 print_hello 함수를 전달했습니다.
  • decorator 함수는 wrapper 함수를 리턴합니다. 이를 decorated_print_hello라는 변수에 할당했습니다.
  • 해당 변수의 타입은 함수이므로, 그대로 호출하면 wrapper 함수가 호출되며 '함수가 실행됩니다.'라는 문자열이 출력되고, 전달했던 print_hello 함수가 호출되어 'hello'까지 출력되었습니다.

Decorator expression

일반적으로 위와 같이 함수를 넘겨주고, 함수를 받고, 그걸 다시 실행하는 복잡한 구조는 잘 사용하지 않습니다. Python은 데코레이터를 쉽게 사용할 수 있도록 @ 심볼을 제공하며, 이 부분은 Java의 어노테이션과 비슷합니다.

인자가 있는 함수 데코레이팅하기

인자를 가진 함수를 데코레이팅하고 싶다면, 내부(wrapper) 함수에 *args**kwargs를 추가하면 됩니다.

여기서 wrapper 함수는 데코레이팅과 함께 인자를 중계해주는 형태입니다.

'Python 계열 > Python 레거시 글' 카테고리의 다른 글

[Python] Generator  (0) 2018.07.23
[Python] Iterable, Sequence, Iterator  (0) 2018.07.22
[Python] Closure  (0) 2018.07.20
[Python] 문자열의 메모리 할당 방식  (0) 2018.07.19
[Python] 함수 인자의 기본값 평가  (0) 2018.07.14

Python의 함수는 값이며, 몇 가지 추가적인 특징(변수 할당, 매개변수 전달, 반환값으로 사용 가능 등) 때문에 일급 객체로 분류할 수 있습니다. Python은 함수 안에 함수를 정의할 수 있으며, 그렇게 정의된 내부 함수는 외부 함수의 문맥에 접근할 수 있습니다. 쉽게 말하면, 외부 함수가 가지고 있는 지역변수에 접근할 수 있다는 것입니다.

calculator라는 함수를 정의했고, 이 함수는 두 개의 인자를 받아 처리하는 함수 fn, 두 정수 a, b를 받습니다. 함수 내부에는 sum함수가 정의되어 있습니다.

  • 만약 fn이 전달되었다면(if fn) 인자 a와 b를 전달하며 해당 함수 fn을 호출하고, fn의 반환값을 반환합니다.
  • 만약 fn이 전달되지 않았다면(else) 내부 함수인 sum을 호출합니다.

함수의 인자로 함수를 전달하는 일은 낯설지 않지만, calculator 함수의 내부 함수인 sum 함수는 아무 인자를 받지 않았음에도 변수 a와 b에 접근할 수 있습니다. 이처럼 내부 함수가 외부 함수의 지역변수에 접근할 수 있는 것을 클로저(Closure)라고 하며, 데코레이터와 같은 Python의 고급 개념들을 위해 필수적으로 사용됩니다.

+ Recent posts