콘텐츠로 건너뛰기
Home » Python » 페이지 13

Python

제너레이터 타입검사 (파이썬)

[[코루틴과 병렬처리]]에서 잠깐 다뤘지만, 제너레이터 타입인지를 검사하기 위해서는 types 모듈의 GeneratorType 클래스를 이용하면 된다. someGenerator = someGeneratorFunc() import types isassert isinstance(someGenerator, types.GeneratorType)

argparse – Python 명령줄도구의 인자분석

케이스별 실제 사용 예 위주로 정리한 새 글이 있으니 참고하세요.

argparse

https://docs.python.org/3/library/argparse.html?highlight=argparse#module-argparse

CLI툴을 만들 때 다양한 옵션 스위치들을 제공하려는 경우, 이를 일일이 파싱1하는 것은 사실 쉽지 않다.파이썬에서는 argparse 모듈이 이러한 작업을 보다 편하게 할 수 있게 도와준다. 더 보기 »argparse – Python 명령줄도구의 인자분석

파이썬의 제너레이터와 코루틴

파이썬 제너레이터는 특별한 종류의 함수 객체이다. 함수 내부에서 yield 구문을 사용하여 특정 값을 내놓은 후에도 실행을 종료하지 않아 제거되지 않고, 다시 그 자리에서부터 이어서 계산을 반복하고 다시 값을 내놓을 수 있다. rangemap, filter 등의 객체가 제너레이터의 일종이라고 할 수 있다.

아주 먼 옛날, 파이썬 2.5에서 제너레이터에 특별한 기능이 생겼는데, 바로 제너레이터 속으로 값을 전달하는 기능이다. (PEP342) 이는 매우 흥미로운 패턴으로 이어지게 되는데, 실행 중 한 번 yield 문을 만나 자신의 위치를 기억하고 있다가 다시 그 자리에서 실행이 가능하다는 점에서 두 개 이상의 제너레이터가 서로 값을 주고 받으면서 교차식으로 실행하는 것이 가능하다. 이는 일반적인 함수 호출의 패턴인 주 루틴 – 서브 루틴의 관계와 달리 두 개의 루틴이 함께 실행된다는 부분에서 코루틴(coroutine)이라고 부른다.

코루틴은 사실 완전히 새롭게 등장한 개념은 아니었다. 이미 6~70년대에 기반이 닦여진 기술이이었다. 당시에는 작업 흐름의 분산을 위한 여러 가지 개념들이 도입되고 시도되고 있었는데, 이 당시에 이러한 기술들 중에서 가장 환호를 받았던 것은 다름 아닌 멀티스레드였다.

멀티스레드가 큰 인기를 얻고 발전해 나가면서 상대적으로 코루틴은 거의 방치되다 시피하였으나, 규모가 커짐에 따라 멀티 스레드는 자원 경쟁이라든지 동기화문제 등 더 큰 골칫거리를 가져왔다. 이러한 문제로 인해 코루틴 개념은 그린릿(greenlet)이나 경량스레드(lightweight thread)라는 이름으로 재발견되어 주목받는 경우도 있다.

코루틴이 흥미로운 지점은 멀티스레드 없이 하나의 스레드 위에 여러 개의 실행흐름이 존재할 수 있다는 것이다. 즉 멀티스레드에서의 골치 아픈 문제들을 끌어들이지 않고서도 실행 흐름을 분산할 수 있다는 것을 의미한다.

하지만 분산처리와 같은 상황이 아니더라도 제너레이터 혹은 코루틴은 파이썬 프로그래밍에서 매우 중요한 비중을 차지한다. 멀티스레드와 같은 적극적인 동시성이 아니더라도, 제너레이터의 ‘느긋한(lazy)’한 특성은 실제로는 concurrent 하지 않은 작업들을 마치 동시에 진행되는 것처럼 다룰 수 있게 하며, 무거운 연산을 가능한 뒤로 미루어 실행 시간내의 체감 퍼포먼스가 좋은 것처럼 보일 수 있게 한다. (사실 이정도면 충분한 것이, 파이썬의 멀티스레드는 실제로는 동시에 실행되지 않기 때문이다.)

이 외에도 제너레이터와 코루틴은 간단한 클래스를 대체할 수 있으며, 일련의 처리 과정에서의 단위 작업을 구성하고 이들을 선언적으로 연결하는 방법으로도 활용할 수 있다. 오늘 이 글에서는 제너레이터와 코루틴에 대해 알아보도록 하자.

더 보기 »파이썬의 제너레이터와 코루틴

파이썬의 새로운 병렬처리 API – Concurrent.futures

컴퓨터 프로그램이 어떤 일을 처리해 나가는 실행 흐름은 기본적으로 선형이다. 서브루틴을 실행하는 것은 실질적으로 현재의 실행흐름이 해당 루틴의 단계까지 내려갔다가 다시 복귀하는 것이며, 하나의 CPU는 마치 고속도로에서 차선을 바꿔타듯 코드를 진행하며 작업을 처리해나간다. 하지만 두 개의 차선에서 동시에 다른 작업이 진행되어야 하는 상황이 언젠가는 필요할 수 있을 것이다.

이전에는 이것을 ‘동시성’이라 불렀고, 파이썬에서는 기본적으로 threading.ThreadMultiprocessing.Process 를 이용해서 다중 스레드 및 다중 프로세스를 통해서 동시성 작업을 처리했다. 이들 라이브러리 이전에 _thread 라는 저수준 API가 존재했었지만, 지금은 잊어도 좋을 것 같다.

파이썬 3.2에서는 ‘동시성’에 관한 개념을 발전시킨 고수준 API를 제공하여 더 나은 형태의 코드를 작성할 수 있게끔해주는데, 그것이 바로 오늘 소개할 concurrent.futures 라이브러리이다.

이 새로운 API는 기존의 멀티스레드 관련 API를 완전히 대체하지는 않는다. concurrent 모듈은 여전히 내부적으로 _thread와 같은 기존 API에 의존하고 있는 것도 사실이며, 스레드나 프로세스를 저수준에서 세세하게 제어하는 수단을 모두 제공하지도 않는다.

다만 주목할 것은 자바스크립트의 Promise 개념과 비슷한 Future라는 개념을 도입했고, 결과적으로 분산처리 및 그외 동시성에 관련된 코드를 좀 더 편하게 작성할 수 있게 해준다.

더 보기 »파이썬의 새로운 병렬처리 API – Concurrent.futures

체를 사용하여 소수 집합 구하기

가장 빠른 알고리듬 현재까지 순수 파이썬으로 작성된 알고리듬 중 가장 빠른 것으로 알려진 것은 @Robert William Hanks가 개발한 아래 알고리듬이다. def primes(n): """Return a list of primes under n""" sieve = [True] * (n/2) for i in xrange(3, int(n**0.5)+1, 2): if sieve[i/2]: sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1) return [2] + [2*i+1 for i in xrange(1, n/2) if sieve[i]]

정규 표현식의 조건절

흔히 쓰이는 경우는 아니지만 정규 표현식에도 조건절을 사용할 수 있다. 참고로 모든 정규식 엔진이 조건절을 지원하는 것은 아니다. (javascript 정규식은 조건절을 지원하지 않는다.) 만약 현재 사용하는 편집기나 언어의 정규식 엔진에서 조건절을 지원한다면, 조건절을 사용해서 보다 정교한 매칭을 하는 것이 가능하다. 오늘은 정규표현식의 조건절 사용법에 대해 살펴보도록 하겠다.

더 보기 »정규 표현식의 조건절

소인수분해 구현하기

소인수분해(prime fatorization)는 어떤 합성수를 소인수의 곱으로 표현하는 것을 의미한다. 12는 합성수이며, 1, 2, 3, 4, 6, 12 로 나눠질 수 있다. 이렇게 어떤 합성 수를 인수의 곱으로 표시하는 방법은 다양하지만, 소수들의 곱으로 표현하는 방법은 (순서를 무시하면) 하나의 방법만 존재한다. 12 = 2 * 2 * 3 으로 표시할 수 있다.

소인수 분해를 사용하면 약수의 개수나 모든 약수의 합을 좀 더 쉽게 계산할 수 있다. 물론 이것은 연필과 종이를 사용할 때에 적용될 것 같은 이야기이다. 컴퓨터를 사용하는 소인수 분해의 경우, “소수인 인수를 정하는 것”에 제법 시간이 소요될 수 있기 때문에 실제로 그리 크지 않은 범위의 수에 대해서는 무식하게 루프를 돌면서 나눠보는 것으로 약수를 세거나 더하는 방법이 더 빠를 수 있다.

더 보기 »소인수분해 구현하기

Task, Future, Coroutine

코루틴과 Task에 대한 내용을 발행했었는데 이 부분은 사실 asyncio에 대한 총정리 글에 포함되는 내용이었던 관계로, asyncio 에서 사용되는 세 가지 대기 가능 객체인 Task, Future, Coroutine 의 차이에 대해서 설명하는 내용으로 수정합니다.


asyncio는 비동기 처리를 위해 비동기 코루틴을 만들고 이를 스케줄링하여 실행하는 기능을 중심으로 구성되어 있다. 그런데 관련 함수를 찾아보면 어떤 것은 코루틴, 또 어떤 것은 Task나 Future로 표현하며 섞어 쓰는 것 같기도 해서 혼란스러운 점이 있다. 이 글에서는 코루틴과 asyncio.Task, asyncio.Future 가 각각 어떻게 다른지 살펴보도록 하겠다.

더 보기 »Task, Future, Coroutine

사전식 순열의 다음 항 구하기 (파이썬)

참고 : http://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order 사전식 순열 생성 함수 어떤 원소들의 순열을 구하는 많은 알고리듬이 있다. 파이썬의 itertools 모듈은 순열, 조합 생성을 하는 permutations(), combinations() 등의 함수를 제공한다. 이 블로그에서도 이 외에 특정한 집합에 대해 N 번째 순열을 구하는 문제도 다뤄본 적이 있다. 오늘은 특정한 수열이 주어졌을 때, 해당 수열의 원소들로 구성되는 사전식 순열에서 다음 번 순열을 구하는 문제를 생각해보자. 사전식 순열이란 특정 집합의 원소들로 이루어진 모든 순열을 정렬하여 순차적으로 나타내는 순열을 말하는 것이다. 예를 들어 [1,2,3,4]는 오름차순으로 정리되어 있으므로 사전식 순열에서는… 더 보기 »사전식 순열의 다음 항 구하기 (파이썬)

셸 정렬 (Shell Sort)

셸 정렬은 정렬 방법의 원리로만 보자면 “분할 증분 정렬”(diminishing incremental sort)이라고도 불리는 방법이며, 굉장히 오래된 정렬 알고리듬 중 하나이다. 이 정렬 방법은 삽입 정렬을 근간으로 하면서 삽입 정렬의 성능을 간단한 아이디어로부터 크게 증가시키는 방법이다.

삽입 정렬은 왼쪽에 있는 원소부터, 그 원소가 이동할 수 있는 ‘가장 왼쪽 자리’에 그 값을 삽입하여 정렬해 나가는 방식이다. 이 때 ‘삽입’을 위한 공간을 만들기 위해 원래자리부터 삽입될 자리 사이의 값들이 하나씩 오른쪽으로 이동해야 한다. 따라서 삽입 정렬은 어떤 원소가 이동해야 할 거리가 크면 클수록 효율이 떨어지며 배열이 반대로 정렬되어 있는 경우가 이에 해당할 것이다.

더 보기 »셸 정렬 (Shell Sort)