요즘 블로그에 통 글을 안 써와서 거의 폐가와 같이 되어 가고 있었는데요.. ^_^
다름이 아니라, 제가 "이러면 좋겠다!"하고 생각해왔던 바로 그런 성격의 너무 좋은 분을
만나게 되어서 다른 곳에는 신경 쓸 시간이 없었네요. 이히히;
그래도, 1달에 1개 정도는 유지해 두고자;; 쌓아뒀던 코드 단편 하나를 올려 봅니다. 헤헤.
종종 아주 긴 리스트에서 자원관리를 하면서, 자원을 순차탐색으로 할당해야하는 경우가 있습니다.
주로 자원이 직접 사람이 쓰는 것이거나 해서, 순서대로 가는 것이 인지적으로나 쓰고 있는
자리가 모아지는 점에서 유리한 경우에 그런데요. 도서관 같은 곳에서 좌석을 배정한다거나,
DHCP서버에서 IP 주소를 나눠준다거나, 순차적으로 나눠주는 큐 관리 시스템에서 작업을
나눠줄 빈 큐를 찾는다거나 생각보다 제법 많습니다.
이런 경우에, 10번째부터 순차검색하기 시작했으면 끝까지 돈 다음에 처음부터 9번째까지 돌아야
하는 것이 중심원리(?)인데요. 구현하는 방법은 물론 클래스 인스턴스가 최근 찾은 인덱스를
변수로 들고 있다가 그 인덱스부터 끝까지 한 번 돌리고, 처음부터 시작한 인덱스까지 다시
돌리는 방법이 가장 평범하겠습니다. 완전 순서대로 배정할 필요는 없고 대충만 맞으면 되는
경우다 싶으면, FIFO 큐 같은 것도 괜찮은데, 이걸 쓰면 시간이 지날 수록 여기저기 듬성 듬성
나와서 원래 목적과는 달라질 수도 있고요~
그래서 range 2번 돌리는 폼 안 나는(?) 코드 대신 보통 끊임없는 이터레이터에서 개수 제한하는
트릭으로 많이 쓰이는 zip을 섞어서 이렇게 하면 비교적 폼 나게(;;) 연속 검색이 가능한
순차검색이 되겠습니다~
못 찾으면 전체를 한 번 돌고, 찾으면 거기서 중단하면 그 다음에 시작하면 거기서부터 시작합니다~
여기서 종종 마지막으로 돌았던 놈에서부터 다음에 찾을 때 시작하고 싶은 경우가 있는데요. 비슷한 것이 아쉬운 사례로, itertools.takewhile을 쓰면 처음엔 조건이 맞을 때까지 다 가져오는 것은 좋은데, 그 다음 원소를 가지고 오고 싶어서 .next()하면 이미 조건 맞는지 보려고 갖고간 바람에, 조건 안 맞는 것 가져오는 목적으로 그 다음 이터레이터를 쓰지 못하는 것이 엄청 불편합니다.
그래서 전에 찾았던 부분에서 다시 시작하도록 해 보자면~
fromitertoolsimportizip,cycledefcontiters(L):cycleiter=cycle(L)indicesnonfirst=xrange(len(L)-1)defgeniter(keeping=[cycleiter.next()]):yieldkeeping[0]forelem,_inizip(cycleiter,indicesnonfirst):keeping[0]=elemyieldelemreturngeniter# 테스트 부분은 동일
네~ 좀 지저분하긴 해 졌는데요;; 실행하면 이렇게~
a b c
c d e f a b
b c d e f a
모르는 것을 보면 전혀 못 알아볼지라도 찾아보기 좋아하는 어떤 분(^_^)을 위해 용어에 좀 과도하게 링크를 걸었습니다 ^^;
파이썬 역사상 가장 큰 개혁인 3.0이 발표된 지 이제 한 달이 되어 갑니다.
이번 업데이트는 워낙 변한 것이 많아서 파이썬 개발팀 내부에서도 실제 개발에 적용되려면 2년은
걸릴 것으로 보고 있는데요. 그래서 중간 징검다리로 파이썬 2.6이 3.0을 전후로
발표되었습니다. 2.6에는 3.0 대비에 대한 기능이
많이 들어갔는데, 이 부분만 간단하게 맛보기로 소개해 드립니다~
파이썬 3.0 호환 대비 옵션
파이썬 2.6에서는 3.0에 대비하는 개발자의 편의를 위해서 -3 옵션을 지원합니다.
파이썬을 띄울 때 -3 옵션을 주면 3.0 호환성 경고가 뜹니다. 예를 들면 이렇게요~
이렇게 파이썬 3.0에서 없어지면서 대체할 수 있는 것을 쓰면 경고가 뜹니다.
옵션으로 주지 않고 프로그램 안에서 옵션을 넣어준 것 처럼 하려면
sys.py3kwarning 을 True로 설정해 주면 됩니다. 프로그램 안에서는 sys.py3kwarning을 보면
-3이 설정되었는지 알 수 있지만, 파이썬이 뜨고 나서는 바꿀 수 없습니다.
파이썬 3.0 호환 빌트인 함수
파이썬 3.0에서 새로 생기거나 동작이 바뀌는 빌트인 함수를 2.6에서 미리 쓸 수 있습니다.
그냥 3.0을 바로 쓰는 것과 무슨 차이냐 하면, 기존 2.x용으로 개발된 프로그램 안에서도
모듈 하나 안에서만 선택적으로 빌트인 함수를 3.0 것으로 바꿔서 3.0인 것처럼 쓸 수 있는
것이죠. 하나씩 이렇게 3.0용으로 바꾸다보면 돌아가는 상태를 유지한 채로 2.x에서 3.0용으로
부드럽게 넘어갈 수도 있고요~
>>>fromfuture_builtinsimport*>>>map(int,'12345')# 파이썬 3에서 이터레이터로 바뀌는 map<itertools.imapobjectat0x833deec>>>>_.next()1>>>ascii('한')# 기존의 repr()을 대체하는 ascii()"'\\xed\\x95\\x9c'"
파이썬 3.0에서 바뀌는 문법 미리 맛보기
파이썬 3.0에서 바뀌는 print나 유니코드 문자열, 바이트 문자열 같은 것들을 모듈 단위로 미리 쓸 수도 있습니다. 마찬가지로 부분 부분 대처를 해서 3.0용으로 부드럽게 넘어갈 수 있겠죠.
종종 파이썬에 대한 평을 인터넷에서 한 번씩 검색해 보는데요. 많은 분들이 가장
많이 싫어하는 것은 뭐니뭐니 해도 "들여쓰기 강제"겠죠. 뭐 이거야 취향 문제라
어쩔 수 없는 것이고. 사실 파이썬 사용자들 중에서 "들여쓰기 강제"를 좋아하는 사람이
많기 때문에 파이썬의 원래 목적에도 더 맞다고 생각되고... ^.^;
그에 못지않게 자주 지적되는 것이, 객체 안에서 꼭 self.를 달아 줘야 된다는 것인데요.
저는 self.를 항상 명시적으로 붙이는 거야말로 파이썬의 참 매력이고, self가 없어지면
파이썬이 무너진다고 생각합니다! 특히 자바 프로그래머들이 파이썬의 self에 대해
많이 지적하는데, 자바와 파이썬 모두에서 영향력이 있는 브루스 엑켈도 self를
(메쏘드 선언에서만이라도) 없애보자 했는데, 그에 대한 응답으로 귀도가 불가능한 일이다라고
그 이유를 논리적으로 설명했었습니다.
브루스 엑켈의 제의가 선언에서만 없애자는 것이었기 때문에, 메쏘드 내부의 코드에서
없애면 안 되는 이유에 대해서는 귀도가 설명하지 않았는데요. 브루스 엑켈이 스스로 결론 내린
그 앞 부분의 문제 "self가 왜 있어야 하냐!" 그 이유에 대해서 좀 설명해서
자바 프로그래머 분들이 파이썬을 좀 더 이해할 수 있도록 도와볼까 합니다.
파이썬에서 self가 붙게 된 역사적인 이유는 파이썬의 클래스 내 메쏘드는 기본적으로
외부에 독립되어 있는 함수에 껍데기를 씌운 것이기 때문입니다. 자바는 아예 독립 함수가 없고,
다른 언어에서는 대체로 독립된 함수들과 메쏘드는 다른 취급을 받는데, 파이썬에서는 그냥
함수를 메쏘드로 편입시켜서 쓸 수도 있고, 둘을 비슷한 방법으로 바꿔서 다룰 수 있습니다.
예를 들면 이런 코드가 가능하겠죠.
밖에서 선언된 함수를 클래스 정의할 때 메쏘드로 끌어들인 것이죠. 메타클래스를 쓴다면 더
동적으로 해 버릴 수도 있습니다. 도대체 이런 코드를 뭐에 쓰냐! 하는 의문을 가지실 수도 있는데요.
의외로 이런 기술이 많이 쓰입니다. egg함수를 C로 구현된 확장모듈에서 끌여들일 수도 있고요.
egg만 사용자가 구현할 수 있도록 노출시켜서 외부 모듈에서 불러올 수도 있고요. 심지어
R이나 .NET같은 브릿지에서 다른 언어로 구현된 것을 쓸 수도 있습니다. 메쏘드가 결국
함수기반이라는 것은 생각보다 강력한 개념으로, __로 시작하는 내부 속성을 쓰면 더욱 희한한 것도
제어할 수 있게 되고, 클래스를 안 쓴 코드와 클래스를 쓰는 코드 사이를 넘나들거나 점진적으로 변경할 때 아주 쓸모가 있습니다.
파이썬에서 instance.method(A, B) 는 class.method(instance, A, B) 와 같은 역할을 합니다.
이것은 함수가 메쏘드가 된 얘기 외에도, 다중상속을 받았거나 이름이 중복되는 메쏘드를 부를 때 쓰이기도 하고, 다양하게 상속받은 하위 인스턴스들을 명시적으로 한 메쏘드에게 콕 찝어 줄 때도 쓰이고, 이 규칙 하나가 수많은 모호함을 해결해 줍니다. 그래서 이 일관성이 문법 전반에 계속 흐르고 있습니다.
그렇다면 그냥 함수는 함수로 쓰고 메쏘드는 메쏘드로 쓰고 같은 데서 상속받으면 비슷한 인터페이스가
나올 수 있지 않겠느냐 하는 의문이 있을 수도 있습니다. self의 또 다른 존재 이유로 파이썬을 파이썬으로
만드는 가장 중요한 특징인 "네임스페이스"가 등장합니다.
"네임스페이스"는 파이썬에서 변수를 담아두는 공간으로, 원래는 로컬, 모듈 전체, 빌트인 세 가지 네임스페이스를 찾도록 되어 있다가, 파이썬 2.1부터 상위에 싸여있는 것들도 찾도록 돼 있습니다. 이해를 돕기 위해 예를 들어드리면
A=1defX():B=1defY():C=1print(A)D=1
이런 파일이 있다면 A는 모듈 전체, 나머지는 로컬에 들어갑니다. 그런데 Y()의 입장에서 C는 로컬인데, B와 D는 자기 로컬은 아니면서 상위 네임스페이스에 속한 변수들이 됩니다. 따라서, 파이썬 2.1부터는 모듈 전체로 가기 전에 B, D가 있는 X영역부터 찾습니다. 파이썬은 변수 선언을 하지 않기 때문에, 변수의 네임스페이스는 대입이 한 번이라도 일어난 최소의 네임스페이스에 영역을 잡는데요. 위에서 C는 Y()안에서 대입이 있었기 때문에 Y()안의 네임스페이스에 잡히고, B, D는 X()에서 대입이 있기 때문에 X()의 네임스페이스에 잡힙니다. 그런데, A는 대입이 모듈에서만 있고, X()에는 없어서 X() 로컬이 아니라 글로벌로 잡힙니다.
이런 네임스페이스를 바꿔주는 키워드가 원래부터 지원되는 global과 파이썬 3.0부터 지원되는 nonlocal이 있습니다. 이건 따로 관심이 있으시면 매뉴얼을 보시면 되겠습니다. +_+
여기서 갑자기 웬 네임스페이스 설명을 self하는 데 하느냐! 하면..
self.을 생략하게되면 로컬 네임스페이스와 인스턴스 네임스페이스가 섞이게 된다는 것입니다. 즉 클래스에서 x = 1하면 이게 로컬로 갈 지, 인스턴스로 갈지 모호해 지는거죠. 자바나 C++은 명시적으로 선언을 하기 때문에 헷갈리지 않지만, 파이썬은 선언을 않기에 명시적으로 쓸 필요가 있죠. 그래서 펄이나 루비에서는 따로 @나 !같은 기호를 도입해서 쓰는데.. 파이썬의 원칙 중 매우 중요한 것으로 "연산자 너무 늘리지 말자"가 있어서 고려 대상은 아닙니다. self.라고 쓰면 파이썬 문법을 모르는 사람도 아 이게 뭐구나! 하고 추측을 할 수 있지만 @같은 걸 붙여놓으면, 문법책을 참조하거나 고난도의 눈치를 보지 않고서는 인스턴스 네임스페이스인지, 클래스 네임스페이스인지, 글로벌 네임스페이스인지 알기가 힘들겠죠.
그럼 또 제기될 수 있는 의문! 대입은 그럼 명시적으로 하고, 쓸 때만 인스턴스와 클래스도 한 번 타 주면 되지 않겠니? 하고 소극적인 부탁을 해 볼 수도 있겠는데요. 읽는 방법, 쓰는 방법이 다른 건 아무래도 파이썬 원칙에는 맞지 않고, 속도도 많이 느려집니다.
모호한 것을 보면, 추측할 수 있을 거라는 유혹은 단호하게 거절한다. (In the face of ambiguity, refuse the temptation to guess.) -- 팀 피터스, 파이썬의 선(Zen)
파이썬 3.0 새 소식이 나오면 가장 많이 궁금해 하실 부분이, "지금 파이썬을 배우려면 3.0을 배워야 하냐 2.x를 배워야 하냐"하고, "프로그램이 다 2.x용으로 돼 있는데 3.0으로 어떻게 넘어가냐" 일텐데요.
우선 1번) 파이썬 3.0은 하위호환성을 상당 부분 포기했기 때문에, 당장은 업계에서 2.x를 계속 쓰게 될 것입니다. 파이썬 2.x와 3.0이 겉보기에는 문법 차이가 좀 있는 것처럼 보이지만, 파이썬의 기본 이념은 그대로 가지고 있기 때문에 우선 파이썬 2.x를 배운 다음에 3.0 문법을 나중에 배우는 것은 별 일이 아닙니다. 지금 배운다면 2.x를 배우고 쓰시다가, 좀 익숙해진 다음에 3.0에서 다른 게 뭔지 한 번 봐 두시면 됩니다.
2번) 파이썬 2에서 3으로 넘어가는 것은 거의 모든 파이썬 프로그램이 다 2~3년 안에는 겪어야 할 일이기 때문에, 미리 파이썬 3.0을 디자인하면서 자동으로 문법을 변환할 수 있을 것인가! 같은 것까지도 고려 대상이 됐습니다. 그래서 파이썬 3.0에는 2to3이라는 프로그램이 들어있는데, 이걸 사용하면 웬만한 것들은 대부분 자동으로 파이썬 3.0용 프로그램으로 변신할 수 있습니다. 그리고, 파이썬 2.6이 파이썬 3.0을 대비하기 위한 중간 계단으로 같이 나왔습니다. 파이썬 2.6을 쓰시면 파이썬 3.0에 아주 잘 대비된 프로그램을 만들 수 있습니다. 2.6에도 2to3이 같이 들어 있습니다.
참, 그리고 파이썬 3.0 최종판에는 아쉽게도 텔레파시 지원은 예정과 다르게 빠졌지만,
반중력 비행 기능이 생겼습니다. x로 시작하는 모 사이트에 따르면(!) 파이썬에서 import antigravity를
했더니 날 수 있었다고 합니다! (한 번 해 보세요!)
스크립트에서 같은 작업을 많은 데이터에 반복할 때, 한 번 도는데 엄청나게 오래 걸리거나
다른 사이트 리소스를 쓰기 때문에 괜히 민폐를 안 끼치려고 앞 부분만 테스트하는 게 좋을 때가 많습니다.
한 번만 돌릴 때는 이렇게 보통..
forurlin엄청많은URL:f=urllib.urlopen(url)# 한 번에 확! 하기는 좀 귀찮은 작업을 한다raiseSystemExit# 여기서 그냥 1번만 돌고 종료
종종 첫 데이터는 엄청 단순해서 한 5개나 앞쪽 10개만 돌려보고 싶을 때, [:5]나 [:10]하면 좋겠죠.
그런데, 어떤 건 이터레이션은 되지만 이터레이션 자체가 자원을 많이 먹거나 민폐를 끼치거나
하는 경우가 있습니다. 그 때 뭐 제한하려면 enumerate같은 걸 써서 i >5 면 중단 이러면 되겠지만
역시 너무 순수해 보여서 지루하고 타이핑도 많아서 귀찮습니다. 그래서 제가 보통 쓰는 방법
cd=list('12345')forurlin엄청많은URL:# 다른 작업cd.pop()
왠지 12345 일일이 써 주면 아! 다섯번 하는구나! 하는 필이 확 오고, 에러로 끝내주니까 아주 신납니다. :)
며칠 전에 올린 글에서 파이썬을 "지는 해"라고 표현했던 것이 많은 분들의 반향을 일으켰는데요~
파이썬이 망해간다는 걸로 이해하시는 분들이 많아서, 의도를 명확하게 하려고 좀 부연 설명을 달아 봅니다.
"뜨는 해"인 언어들의 특징은 이런 게 있습니다.
주로 좋다고 하는 사람들은 초괴짜 개발자 아니면 손보다 입으로 더 많이 개발하는 컨설턴트들이다.
뭔가 사소한 문제가 생기면 해결법을 찾는게 무척 재미있다. 그렇지만 보통 한 나절은 걸리고, 결론적으로 인터프리터나 표준 라이브러리를 고쳐서 본의 아니게 "오픈소스에 기여"하게 되어 뿌듯하다.
대부분 사람들은 해 보면 재미있겠다고 생각하지만, 실제로 회사에서 쓰게 되면 그 날로 발목 잡혀서 휴가도 못 간다. 그래서 감히 해 볼 엄두를 못 낸다.
라이브러리나 문서를 찾다보면 없어서 결국 "아 재미있겠는데!"하고 한참 재미를 보다보면, 본의 아니게 라이브러리도 만들고 문서도 쓰고 해서, 자기 이름이 검색엔진에 많이 걸리고 알아보는 사람이 늘어난다.
반면에 "지는 해"인 언어들은 이런 게 있겠죠.
특별히 회사에서 얘기를 안 해도 상사가 이번 프로젝트에서 그 언어를 써 보면 어떻겠냐고 추천한다.
더 이상 제품 설명서나 홍보에 "이 제품은 어떤어떤 언어로 만들었습니다."를 안 적는다.
뭔가 몰라서 검색엔진이나 게시판을 찾아보면 똑같은 문제를 다른 사람이 다 겪어보고 경험을 적어놔서 따라하면 된다.
그 언어를 하는 사람을 찾는 구인 광고를 자주 본다.
라이브러리가 필요해서 찾으면 이미 여러 개가 있어서 뭐가 좋은지 보고 받으면 된다.
저는 이미 한국에서 파이썬이 적합한 분야에는 적절한 빈도로 사용되고 있다고 봅니다. SI나 시스템관리, 게임, 그래픽, 운영체제 같은 전통적인 컴퓨터 분야 뿐만 아니라, 과학계산, 기계공학, 생산관리, 음악, 아파트, 전화기 등등 수많은 분야에서 도입돼서 쓸만한 분야에서는 웬만한 개발자들은 "파이썬"을 한 번 쯤은 들어봤습니다. 이제 여기서 더 파이썬을 쓰는 곳이 늘어난다면, 그건 파이썬이 잘 해서라기 보다는 그냥 그 분야가 확장됐다거나 변화했다고 볼 수도 있을 정도입니다.
"지는 해"라고 "망해가는 언어"가 아니라, 이제 뜨는 과정이 어느 정도 됐으니 큰 고생 없이 쓸 수 있다는 것을 의도했습니다. 해는 대략 12시에 중천에 뜨지만, 사람들은 대부분 오후와 밤에 생활하지 않습니까? C는 벌써 20년째 지는 해인데도 여전히 많은 분야에서 건재하죠.
얼마 전에 파이썬 3.0으로 가는 길목으로 파이썬 2.6이 공개되었고, 파이썬 3.0 정식 발표가
임박해 있습니다. (현재 예정은 12월 3일)
오늘 드디어 FreeBSD 포트에도 파이썬 2.6과 3.0rc1을 넣었습니다. 아직 디폴트 버전으로 지정하지는 않았고, GNOME이나 KDE같은 주요 의존 포트들에서 대규모 빌드 테스트가 끝나면 올릴 예정입니다. 2.5 때는 사소한 문제가 엄청나게 발생해서 디폴트 되는데만 거의 3달 가까이 걸렸는데 2.6은 바뀐게 별로 없으니 금방 지나가리라 믿습니다;
그런데, 한국에서 파이썬을 "파이썬"이라고 부르게 된 계기를 말로 알려드린 적은 있었지만, 특별히 글로 쓴 적은 없는 것 같아서 3.0 백일기도 하는 마음으로 적어 봅니다. ㅎㅎ;
파이썬은 국립국어원의 외래어 표기법에 맞게 표기하면 "파이선"이라고 표기해야 맞습니다. 외래어 표기법에서는 영어를 한글로 적을 때는 된소리를 안 쓰기 때문인데요.
파이썬이 처음 한국에서 막 뜨려고 하던 2000년 초기에 한국에서 파이썬을 다루는 홈페이지는 광운대 이강성교수님과 당시 서울대에 계시던 이관수님의 홈페이지 밖에 없었습니다. 그 때 이 두 홈페이지에 다니는 사람들이 파이썬을 다양한 방법으로 불렀는데, "파이선", "파이던", "파이똔", "파이톤", "파이싼", "파이딴", "퓌톤", "피톤", "피쏜" 등등 부를 수 있는 조합은 거의 다 나오지 않을까 싶을 정도로 다양하게 불렀죠. 그러다가, 이강성교수님께서 운영하시는 파이썬정보광장 첫 모임이 드디어 2000년 4월 28일 저녁에 역삼동에서 강남대로 따라 양재동으로 가는 길에 있는 백두산이라는 고깃집에서 있었고, 그 자리에 참석했던 대략 20명 정도 되는 최초의 한국 뱀신족들이 파이썬을 "파이썬"으로 부르기로 합의합니다. (당시에 Guido van Rossum을 한글로 어떻게 표기할까에 대해서도 얘기를 했었는데, 이건 결론이 안 났습니다.)
우선, Python의 어원은 그리스어에서 나왔으니 "퓌톤"류의 표기를 좋아하는 의견들도 있었지만, 파이썬 언어 자체는 Monty Python에서 온 것이라 영국식 발음이 원천이고, 귀도도 미국에 살고 있으니 영어로 해야겠다하고 "퓌톤"을 버리게 되었고요. "파이선"이라는 표준 표기 대신 "썬"을 쓴 것은 "파이선"하면 너무 발음이 새고 좀 약해보여서 강하고 새로운 인상을 주자(?)하는 의미에서 "썬"으로 의견이 모아졌습니다.
결국 그렇게 한글 표기법을 정한 이후로, 이름 덕인지 2000~2001년 그 모임에 참석한 분들이 주요 프로그래밍 잡지 기자분들의 도움으로 파이썬 관련 연재를 쏟아내면서, C/C++과 자바 말고는 별 게 없던 지루한 프로그래밍 동네의 수요와 맞아 떨어져 급속도로 "해 본 적은 없지만 언젠가는 해 보고 싶은 언어"로 상당기간 수위권을 달렸고, 지금은 대안언어라고 부르기 민망한 "지는 해" 쪽에 속하는 언어가 됐습니다. :-)
나와 있는 파이썬 책은 대부분 "파이썬 1주일 만에 배우세요!" 아니면 "파이썬으로 뭐시기 하기" 두 부류였습니다. 아무래도 파이썬이 배우기 쉬운 언어처럼 보이는게 주요 마케팅 요소다 보니까, 쉽게 배워서 어디다가 써 먹는 것 밖에 없었는데요. 얼마 전에 전문가 파이썬 프로그래밍(Expert Python Programming)이라는 책의 출간 소식이 발표됐습니다.
그동안 파이썬 자체를 주제로 하면서 초보서적이 아닌 것은 거의 Python Essential Reference밖에 없었기에 무척 기대가 되어서 당장 내용을 살펴 봤습니다. :) 아직 출간이 안 돼서 내용은 못 봤는데 목차가 공개되어 있네요~
다루고 있는 내용은 패키지 관리, 빌드, 네이밍, 테스트 주도 개발, 지속적 통합, 소프트웨어 개발 사이클, 최적화 등이 있어서 전반적으로 파이썬 문법이나 내부 구조에 대한 것 보다는, 오랫동안 파이썬 개발을 하다보면 얻을 수 있는 경험적 지식이 들어 있습니다. 대충 파이썬 고급서가 나오면 아무래도 파이썬 내부구조나 VM자체, 개념 같은 것을 다루지 않을까 생각했는데, 일일이 찾아서 배울 수는 있지만 처음 접근하기가 쉽지 않은 것들을 그런대로 잘 모아놓은 것 같네요~
파이썬을 쓰다보면 언제든 한 번은 만날 만한 것들을 빨리 배울 수 있게 잘 모아놓긴 했지만, 제목과는 달리 전체적으로 소프트웨어 개발 공정에 관련된 것들만 듬성듬성 다룬 것 같은 느낌이 약간 나긴합니다. 그래도 이런 책이 나왔다는 것은 매우 반갑네요. :)
가격은 $40인데 여러 권 사면 할인도 해 준다고 합니다. 신기하게도 한국도 무료배송 지역이군요. -ㅇ-;
파이썬 페차쿠차를 마치고 막 대전에 돌아왔습니다. 오늘은 비도 계속 추적추적 내리고 주말 저녁이기도 해서 걱정이 좀 됐었는데, 90%를 훨씬 넘는 완벽한 출석률로 좋은 시간 가졌습니다~
이번 페차쿠차는 12장으로 줄이고 첫 장, 마지막 장의 시간 제한을 없애는 약간의 변형을 거쳤는데, 원래 예상했던 것 보다 훨씬 다들 준비를 많이 해 오셔서 이렇게 짧은 시간에 많은 얘기를 들은 적이 있을까 싶을 정도로 압축적인 경험 전달이 된 것 같습니다. 다들 어쩜 말씀을 잘 하시는지 그냥 말 하셔도 20초에 딱 맞을 것 같은 분들도 있고.. :) -- 사실 중간에 잠시 생각했던 대로 50명 이상이 참가하는 행사로 키웠으면 발표하는 분들에게 부담감이 좀 가서 제대로 진행되지 못했을 것 같다는 느낌이 들었습니다. 이번에 페차쿠차 경험을 좀 쌓았으니 다음에는 더 크게도 할 수 있을 것 같네요!
우선 정말 다양한 (하나도 겹치는 분야가 없었어요!) 분야에서 파이썬을 쓰시는 분들이 모여서 얘기하다보니 쓰이는 곳을 알았다는 것 뿐만 아니라, 앞으로 뭔가 궁금한 게 있으면 누구한테 물어봐야할 지 알았다는 것도 참 유익했습니다. 회사에서 파이썬을 도입한 과정이나 문제해결 과정을 조금씩 엿볼 수 있었던 것도 다른 곳에서 파이썬을 도입하는 데 어려움을 겪고 있는 분들께 전해주기 좋은 경험이었던 것 같네요.
형식적으로는, 20초는 매우 적절한 시간이라는 느낌을 받았고요, 보통 20초면 시간이 좀 모자라거나 남을 때도 쉽게 따라잡거나 약간 덧붙여서 유연하게 넘어갈 수 있는 아주 좋은 간격인 것 같네요. 그리고 시간 제약이 정확히 있다보니 지나치게 구체적인 설명은 아무래도 피하게 돼서, 대부분이 집중해서 관심있게 들을 수 있고, 질문할 시간이 잊기 전에 오기 때문에 대화를 시작하는 역할까지도 하게 돼서 좋았습니다. 12장도 이번 주제에서는 적절했던 것 같은데, 기술적인 내용 같은 경우에는 어떨지 아직 잘 감은 안 오네요.
이번에는 발표가 모두 13분이 하셨기 때문에 미리 짜면 아무래도 페차쿠차는 처음이라 긴장도 되고 할 것 같아서 아예 순서를 알 수 없게 파이썬의 random.shuffle()을 써서 순간순간 자동으로 슬라이드가 열리게 했습니다. :)
중간에라도 온 사람 이름을 입력한 다음에, 엔터를 치면 "누구님 하세요!" 하면서 그 사람의 슬라이드를 열어줍니다. ^^; 다음에 누가 할 지 모르기 때문에 긴장 없이 들을 수 있습니다.;;; (뒤에 남은 분들은 약간 -ㅇ-)
슬라이드는 이번에 파워포인트, 키노트, 임프레스 세가지 포맷 중 하나로 미리 이틀 전에 제출받았는데, 동영상 출력 기능이 가장 적절한 키노트로 모두 변환한 다음 키노트에서 20초 자동넘김 지정을 해서 QuickTime 동영상으로 만들었습니다. 미리 변환을 동영상으로 주우욱 해 뒀던 건 아무래도 4분이 짧기 때문에 발표자가 바뀔 때 빨리 바뀔 수 있게 한 것인데 괜찮았던 것 같네요.
이번에 발표 동영상은 미지리서치의 도움으로 촬영을 하기는 했지만, 테이프에 문제가 좀 있어서 앞부분 반 정도만 촬영이 제대로 되었구요. 발표자분들이 요청하신 기업기밀보호(^^;)를 위해 편집한 다음에 공개할 계획입니다.
파이썬 뿐만 아니라 분야별, 기술별, 모임주제별 다양한 페차쿠차들이 많이 생기면 좋겠네요~
얼마 전에 파이썬 마을 모임에 대한 얘기를 올리고 많은 분들이 관심을 보여 주셨는데, 제가 한동안 재미있는 삶에 빠져서 놀다가 깜빡해서;;
좀 정리를 해서 구체적인 일정을 정했습니다. ^_^
멍하니 있으면 순식간인 단 48분 만에 다른 12명의 파이썬 경험을 압축해서 빨아들일 수 있는 기회!
지난 번 댓글에서 파이썬에 처음 입문하시려는 분들도 많은 관심을 보여주셨지만,
아무래도 이번에는 경험공유에 강조하기로 했기 때문에, 경험만 알짜배기로 모아서
얘기를 하는 쪽으로 하고 다음에 또 다른 좀 더 큰 모임에서 튜토리얼 섹션 같은 것을
마련하는 쪽으로 마음 먹었습니다. 조만간 꼭 하겠습니다~ :)
다음 주(7월 27일-8월 2일)에 오랜만에 애자일 개발 워크샵 일로 1주일 동안 서울에 머물게 됐습니다. 그래서 서울 방문 기념으로 거의 1년 만에 파이썬 마을 모임을 한 번 하려고 합니다.
지난 번에 다른 행사의 부대행사로 파이썬 관련 세션을 하나 생각하면서, 자기가 파이썬을 쓰는 분야에 대해서 얘기하고 토론하는 걸 좀 생각해 봤었는데요. 최근에 페차쿠차라는 걸 보고 한 번 "내가 파이썬을 쓰는 곳/파이썬으로 만든 것"을 페차쿠차 형식으로 한 번 해 보면 어떨까 생각했습니다.
페차쿠차는 발표 포맷이 정해져 있는데요, 슬라이드 20장을 각 20초 씩 해서 총 6분 발표를 해야합니다. 보통 많은 사람들이 발표하는 곳 가면 거의 반 정도는 발표하는 사람을 제발 끌어내리고 싶은 유혹을 받는데 그런 걸 줄이기 위한 포맷이라고 하네요. 그래서 이번에는 20장은 보통 엄청 오래 한 분 아니라면 회사 기밀까지 나와야할 것 같아서, 12장 * 20초 해서 4분으로 하면 좋을 것 같네요. 중요한 것은 슬라이드는 자동으로 넘어가니까 한 슬라이드에서 시간을 마음대로 조절해서 쓸 수는 없다는 게 페차쿠차의 기본 원리라고 합니다. (다양한 분야에 활용하시는 분들이 참석하셔서 경험을 나누시면 좋겠습니다!)
혹시 장소나 시간에 대해서 좋은 생각이나 제안 (또는 장소제공) 등 남기실 말씀이 있는 분들은 알려주세요. ^^ 대략 인원 추산도 해야하니 참석하실 수 있는 분들 답글 남겨주시면 고맙겠습니다~
종종 한 인스턴스를 대량으로 복제해서 약간씩 바꿔야할 일이 있습니다.
주로 진화 알고리즘 계열이나 고치기 전/후를 비교해야하거나, 엄청나게 바꾼 뒤에
롤백을 해야한다는 등의 경우가 그런데요.
파이썬에서 복사는 기본 타입들은 각각 독특한 방법이 있지만, 보통은
copy모듈을 쓰면 간단합니다.
그런데 철학적(?)인 분위기를 잡으며 경험이 조금 더 많은 사람이 쓱 나타나서
"너 깊은 복사랑 얕은 복사 알아?"라고 할 것 같은 느낌이 언제나 copy를
쓸 때마다 들곤 하죠; 깊은 복사(deep copy)는 참조하고 있는 객체 모두를
복사하기 때문에 속성으로 들어있는 놈들까지 별개의 인스턴스가 돼서
완전히 떨어집니다. 얕은 복사에서는 참조는 복사하지 않고 자신만 복사하기 때문에
리스트같은 것들이 공유가 되는 특징이 있습니다. 물론 얕은 복사가 훨씬 빠르고
자원을 효율적으로 쓰겠죠.
그런데 종종 클래스를 만들다 보면 어떤 것은 깊숙히, 어떤 것은 얕게 해야할 일이
발생하는데요. 그러면 copy.copy를 쓸 수도 없고 copy.deepcopy를 쓸 수도 없고
애매한 상황이 됩니다. 결국은 얕은 복사를 한 다음에 수동으로 깊은 복사를 해 주면
되겠죠. 그래서 좀 더 복사 과정을 자세히 다뤄보도록 하겠습니다.
우선 복사를 하려면 인스턴스를 새로 하나 만들어야 합니다. 여기서 발생하는 문제!
__init__가 호출되면 복사라고 부르기가 애매하겠죠. 이미 초기화된 놈을 다시 초기화하게 되니까..
그래서 __init__는 호출하지 않고 그냥 객체만 생성하는 방법을 써야하는데,
신형 클래스(new style class)냐 구형 클래스(old style class)냐에 따라서 방법이 다릅니다.
__getstate__나 __setstate__ 중 하나만 구현해도 상관은 없는데 그렇게 하면 리턴값이나 받아오는
값이 모두 딕셔너리가 돼야합니다. 위에서는 a는 그대로 참조만 가져오고, b와 c는 복사하는
방식으로 클래스 복사 방법을 지정해 줬습니다. 복사와는 크게 관련은 없지만 pickle에서
저장할 수 없는 속성들 (예를 들어 소켓 같은 것)이 들어있는 클래스는 __getstate__를 지정해 주는
방식으로 특정 속성을 저장에서 뺄 수 있습니다.
바야흐로 초딩도 멀티코어로 오락하는 시대가 오면서 이제 파이썬 GIL 공포가
많은 사람들을 위협하고 있었습니다. 그에 대한 해결책으로 예전부터
병렬 프로그래밍을 위한 여러가지 프레임워크, 예를 들어
MPI, CORBA, PyRO 같은 것들이 나왔지만, 다들 멋있게 모든 걸 포용하는
라이브러리를 만들다 보니 설치가 어렵거나 배우는데 한참 걸리는 게 결국 문제가
돼서 실제로 심각한 개발자 아니면 그냥 "CPU 1개면 충분해요"라고 눈을 반짝거리며
스스로 최면을 걸고 있었던 것이 사실입니다~
그래서 GIL의 파이썬 프로젝트 자체에서의 해결책으로는 공식적으로 결론에 도달한
것은 아니지만 Adam Olsen의 GIL없애기 프로젝트 같은 것도 있었는데,
이번에 몇몇 사람들의 강력한 후원으로 파이썬 2.6과 3.0부터
pyProcessing이 새 이름 multiprocessing
으로 표준 라이브러리로 들어오게 되었습니다.
pyprocessing의 다른 병렬 처리 라이브러리들에 대한 장점은
뭐니뭐니해도 표준 threading 모듈과 API가 같다는 점이겠죠. threading으로 기존에 짜 놓은
프로그램을 그냥 모듈 이름과 클래스 이름 아주 약간만 바꿔주면 쓰레딩 대신 멀티프로세싱을
사용하게 되어서 결국에는 멀티코어를 제대로 쓰는 프로그램이 됩니다. 실제로
쓰레딩같이 모든 변수를 공유하는 것은 아니고, 리턴값만 전달을 받기 때문에
정확히는 좀 다르다고 볼 수도 있지만, 뭐 "그렇게 짜면 왕변태"라고 선언하면 되겠죠. ㅎㅎ;
그래서 실제로 쓰는 모양을 보려고 옛날에 유행했던 정규식으로 소수 검사를 하는 걸 한 번 돌려 봤습니다.
시간은 대략 9초 정도 듭니다. 그리고 fd 넘겨주기를 지원하는 플랫폼들에서는 소켓도
받아다가 넘길 수가 있으니 네트워크 프로그램도 간단하게 멀티코어를 쓸 수 있습니다.
아주 간단하게 멀티코어를 쓸 수 있는 장점으로 표준 라이브러리로 도입이 되긴 했지만,
아직 문제가 몇 개 있는데요. 대표적으로 FreeBSD에서는 아직 POSIX 1003.1b 세마포어를 "제대로" 지원하지 않기 때문에 FreeBSD에서는 Queue나 Lock등과 관련된 것들을
하나도 쓸 수가 없습니다. (위 예제는 그래서 리눅스에서 테스트할 수 밖에 없었습니다;;)
그 외에 MPI 등의 "심각한" 분산 API들을 쓰던 프로그래머들은 이게 애들 장난이냐 하면서 없는 기능들을 지적할 수도 있는데, 아무래도 표준 라이브러리로써 아주 간단하고
기초적인 기능만 제공하는 것이 목적이고, 셋업이 복잡하거나 거대 프레임워크를 끌고 다니는 경우라면 표준에서 안정적으로 관리하기가 힘들겠죠. 그래서 multiprocessing을
도입하자 주장한 개발자는 이 모듈은 절대 다른 분산 관련 모듈을 쓰지 말라는 의미가 아니고
같이 쓰면 더욱 좋다고 강조합니다.
마지막 줄에서 1:로 굳이 잡아준 이유는 이름 뒤의 ~이 처럼 받침이 없으면 끝에 안 붙는 경우도
처리해 주려고요..
추세 해석
이름의 인기가 늘고 있는지 줄어드는지를 글자로 판단해서 표현해 주기 위해서, 간단한 계산식을
사용했습니다. 우선 원 데이터 자체는 샘플수가 적어서 노이즈가 많기 때문에 보통 많이 쓰이는
9개 윈도우 평균으로 했고, 이렇게 하면 18개 포인트가 나와서 세 부분으로 나눠서
앞 중간 뒤의 평균을 다시 구해서 3가지 값이 나왔습니다. 그래서 눈으로 딱 보면 값이 계속
증가하는지, 올라갔다 내려갔다 하는지를 볼 수 있는데요, 그냥 값으로 볼 수는 없으니
앞/중간 과 중간/뒤의 각각의 변동폭을 0에서 1사이로 정량화해서 봤습니다. 변동폭은 이름마다
절대량이 다르기 때문에 상대량으로 비교해야해서 아래와 같은 식으로 썼습니다.
보기엔 약간 쓸데없이 복잡하긴 하지만, 그냥 상대비율을 (0, 1) 사이로 넣어주는 일 밖에 안 합니다;;;
이렇게 나온 값으로 앞 뒤가 모두 (0.4, 0.6) 구간에 들어오면 "꾸준한 추세입니다."라고 하거나,
앞-중간은 (0.0, 0.3), 중간-뒤는 (0.0, 0.5) 구간에 들어가면 앞 반쪽에서 감소세가 강하고
뒷 반쪽에서 감소세가 둔하다는 의미이므로 "확 줄어들다가 잦아드는 추세입니다."라고 보여주는 식으로
주된 패턴들을 "대충" 느낌으로 나열하는 방법으로 코딩했습니다. 크흐;
구글 차트
이름 전체의 성별 성향이나 이름의 시대적 경향, 이름 글자의 시대적 경향을 보이는 부분에서
구글 차트를 불러서 사용했습니다. 구글 차트는 직접 URL을 코딩하는 방법은 아니고,
pygooglechart를 사용했는데요,
이게 의외로 그런대로 잘 만들어서 웬만한 기능은 불편없이 쓸 수 있게 돼 있더군요. :)
다만, 하나 기술적인 문제가 있었던 부분은 이름 글자의 시대적 경향 같은 경우에는
글자마다 실수값 18개씩(경향)이 저장돼야 하기 때문에, 이걸 그냥 저장하는 건 여러모로
번거롭고 해서 구글 차트 API에서 쓰는 0~4095 사이 인코딩하는 방법으로 썼습니다.
(base64와 거의 같은 방법입니다.) 그래서, 저장은 바로 구글 차트 API URL에 쓰면 되는
형태가 돼서 다시 불러올 때 매우 빠르게 불러올 수 있긴 한데, 문제는 한 이름 안에
이름 앞자와 뒷자의 경향을 모두 보여줘야하기 때문에 둘의 그래프 크기를 제대로 조절해 주지
않으면 각 글자의 크기가 잘못 나온다는 점이었습니다.
그래서 결국 선택한 방법은 보여줄 때 앞자 뒷자 인코딩된 값을 다시 풀어서 큰 쪽의 스케일로
맞춘 다음에 다시 인코딩하는 -.,-; 약간 노가다성 방법을 썼습니다. 역시 이런 부분은
numpy의 array의 도움을 많이 받을 수 있었습니다.
역시 통계 샘플 크기가 작아서 주요 이름들을 빼고는 제대로 된 통계치를 낼 수 없어서
주요 이름들의 성별 경향으로 학습한 걸로 예측하는 부분이 필요했습니다.
이번에는 아예 사용된 적 없는 글자까지도 어떻게 좀 해 보려고
통계치에 전혀 의존하지 않고 그냥 자소별로 분해해서 이름만 피처로 사용하기로 했습니다.
그래서 보통 SVM을
쓰는 것이 여러모로 대세이기는 하지만, 카테고리성(이산) 피처값에 매우 유리한
random forest을 썼습니다.
(물론 제가 수학을 워낙 못하는 것도 큰 요인으로;;;;)
Random forest는 아무래도 쓸 수 있는 구현이 적다는 게 큰 문제인데요.
파이썬에서 쓸 수 있는 orange를 쓰면 정말
좋겠지만, 아쉽게도 이 구현은 리그레션은 지원하지 않고요. Y.Y
R용 패키지인
party와
randomForest
중에 선택해야하는데, party를 먼저 했으나 메모리 3기가를 먹더니 죽었고 (-_-)
randomForest는 안정적으로 대략 200메가 정도 먹고 그런대로 쓸 만한 결과를 줬습니다. :)
학습 기법 측면에서는 남자 샘플이 2배 정도 되기 때문에 편향 문제가 있어서 샘플링 조절을
좀 해야했는데요, 그냥 복잡한 것 쓰지 않고 대략 0.3 밑을 반 다운 샘플링하니까 전체적으로
분포가 윗쪽하고 아랫쪽이 그런대로 맞았습니다. 중성적인 이름이 수가 훨씬 적은 것도 또한
중성적 이름 쪽에서 오차를 많이 발생시킬 수 있는 요인이 될 수 있는데, 이쪽에서 오버샘플링을
하려고 하다가 "될 거 같으면 대충해도 돼야 하는거지" 하는 교수님 말씀이 귓가를 스치며
놀이인데 대충하자 하고 -ㅇ-;; 크흐; 그래서 결국 10-fold cross validation으로
평균 피어슨 연관성이 0.97 정도 나왔습니다. (만... 역시 사람 느낌하고 좀 다른
사례가 개별적으로는 제법 많이 발견되긴 하네요;)
페이지 내용 캐시
서비스를 공개한 다음 날 점심시간이 좀 지나고 나서는 접속이 폭주해서, 실시간 계산이 상당히
있었던 구현 특성상 앞으로 어떻게 될 지 참 고민이 있었는데요; 그래서 마침 전혀 필요없겠다
싶어서 꺼놨던 django의 캐시 프레임워크를
살려서 해 봤습니다.
백엔드를 선택할 수 있는데, 역시 제일 잘 나가는 memcached를 썼습니다. 이거 소문대로 깔끔하고 잘 돌아가네요. ^_^;
Django는 다행히도 템플릿에서 일부만 특정 변수에 따라서 캐시하는 기능이 있어서
이름에 따라 바뀌는 부분, 성에 따라 바뀌는 부분을 따로 따로 캐시하도록 3조각으로
따로 캐시해서 생각보다 훨씬 간단하게 쉽게 캐시로 넣었고요, 지금은 CPU부하가 전보다
같은 요청에서 거의 1/10로 줄어들었습니다! 이히히.
다른 사소한 것들..
몇 분께서 물어보셨던 게 자료처리나 통계처리는 어떤 걸 썼느냐가 있는데, 특별히 쓴 것은 없구요, 파이썬 하나면 다 해결됩니다. -ㅇ-;
물론 numpy, matplotlib도 아주 큰 도움이 됐습니다.
collections.defaultdict를 전에는 그렇게 자주 쓰지는 않았는데, 이번에 좀 과격하게
3~4 단계 쑥쑥 defaultdict를 겹쳐서도 써 봤더니 pickle이 잘 안 되는 문제만 빼고는, 코드를 아주 많이 줄여준다는 점에서
아주 사랑스러웠습니다.
나중에 쓰려고 쌓아두고 있던 간단한 예시인데, 더 이상 쌓이지가 않아서 (--;)
방출해 봅니다;
파이썬 이터레이터/제너레이터는 함축적으로 프로그래밍하는 걸 즐기는 사람들에게는
정말 재미있지만, 절차적 프로그래밍을 하다가 갑자기 이터레이터를 쓰는 게 적응이
잘 안 되는 경우도 많이 볼 수 있습니다. 최고의(!) 파이썬 책으로
유명한 David Beazley가 지난 3월에 PyCon 2008에서 튜토리얼로
시스템 프로그래머를 위한 제너레이터 트릭을 발표했습니다. 여러모로 재미있는 내용인데요~ 저기서는 제너레이터를
주로 다뤘는데, 몇 가지 이터레이터와 관련된 사용 예를 소개해 드리려고요~
(별로 관련 없는 것이 뒤죽박죽;;)
그동안 파이썬은
조건 표현과
과 with절같이
문법을 바꿔달라는 수 많은 사용자들의 요청을 받아들여 문법을 추가한 사례가
여럿 있기는 했지만, switch-case나 for-from-to 같이 디자인 상의
일관성 문제로 인해서 받아들여지지 않은 문법도 많이 있었습니다.
요즘 계속 영역-특정적 언어(Domain-specific Language)에 대한 사용처가
늘고 있는데 파이썬을 특정 목적에 쓰자면 종종 대형 프로젝트에서는 문법을
고치는 게 득이 될 경우도 많이 생각할 수 있습니다.
그래서 전처리기를 사용해서 쓰는 방법도 있지만, python4ply는 이걸 좀 더
깔끔한 방법으로 처리하기 위해 등장했습니다.
나온지는 꽤 오래되었지만, 갈 수록 중요한 변환점을 찍은 모듈로
지속적으로 언급되고 있습니다.
원래 PLY는 파이썬에서 lex/yacc를
지원하기 위한 파서 제너레이터인데, python4ply는 PLY에서 파이썬을 파싱하고
그걸로 파이썬 바이트코드를 생성해서 직접 파이썬 코드 파싱/컴파일을 만들었기 때문에
그 부분을 직접 조절할 수 있도록 했습니다.
파싱과 컴파일을 모두 건드리고 있으니 문법은 원한다면 얼마든지 바꿀 수 있는데,
python4ply는 소스 구조도 아주 깔끔하게 잘 정리되어 있는 편이라, DSL을 만들어야
하는 상황이라면 언제나 유용하게 쓸 수 있을 듯 합니다.
사실 python4ply가 나온 이후로 python-dev 메일링에 누군가 새로운 문법 뭔가 좀
넣어달라, 또는 파이썬 3에 2.x호환성 좀 넣어달라 요청만 올라오면 python4ply
URL을 누군가 덥썩 던져주고서는 그 다음부터는 무시하는 분위기가 됐지요. :>
누구나 어렵지 않게 할 수 있을 거라고 생각하고 있던거지만, 실제로 구현이 되고나니
영향을 꽤 많이 미치고 있는게 역시 가능하다고 생각만 하고 있는 것과 실제 구현체가
나온 것은 영향력이 차이가 좀 있군요.
얼마 전에 "사랑하지 않으면 떠나라"의 서평 제목으로는 좀 독특한 "당신은 자바 가상 머신을 죽일 수 있나요?"라는 글을 보고 떠올라서, 혹시 파이썬을 쓰다가 발생하는 문제를 얼마나 잽싸게 해결하고, 문제가 생길만한 코드를 짜지 않는 등 이해정도와 관련된 것을 시험해 볼 수 있는 문제를 한 번 내 봤습니다. -ㅇ-;; 물론 제가 냈기 때문에 제가 아는 한에서만 나온거라 좀 편향돼 있을 수도 있지만.. 그냥 재미로 한 번;;
1. 다음 파이썬 타입 중에서 "일반적으로" 큰 수를 다룰 수 있는 순서대로 정렬하세요.
decimal.Decimal int/long float (inf 제외) str (36진법으로 풀어 쓴다)
2. 다음 파이썬 타입 중에서 해시가 불가능한 타입을 모두 고르세요.
unicode float set decimal.Decimal dict
3. 다음 중 최대 메모리 사용량이 가장 많은 코드를 고르세요.
(ㄱ) max([i for i in range(1000)])
(ㄴ) max([i for i in xrange(1000)])
(ㄷ) max(i for i in range(1000))
(ㄹ) max(i for i in xrange(1000))
4. 부모 클래스에서 __x(self) 메쏘드가 있을 때, 자식 클래스에서 부모 클래스가 정의된
소스코드를 수정하지 않고 호출할 수 있는 방법을 가능한 한 다양한 방법으로 쓰세요.
5. pymalloc을 넣고 컴파일했을 때 발생하는 현상이 아닌 것은?
(ㄱ) 할당한 메모리보다 더 많이 할당된다.
(ㄴ) 같은 루틴을 반복할 경우 메모리가 샐 수도 있다.
(ㄷ) 할당된 객체가 쓰는 메모리를 해제해도 남아있을 수도 있다.
(ㄹ) 메모리 할당이 더 느려질 수도 있다.
6. 다음 중 메모리 할당 횟수가 가장 많은 코드는?
(ㄱ) map(int, range(100))
(ㄴ) map(str, range(100))
(ㄷ) map(long, range(100))
(ㄹ) map(unicode, range(100))
7. exec "x ** y" 를 실행 할 때 발생할 수 있는 예외가 가장 아닐 "것 같은" 것은?
NameError OverflowError MemoryError TypeError RuntimeError TabError ZeroDivisionError
8. 모듈을 들여오는 과정과 관련된 모듈 또는 객체가 아닌 것을 고르세요? (파이썬 2.x 기준)
sys.path zipfile imp warnings marshal sys.modules __future__
9. x += x 했을 때 할당된 메모리 크기가 변하지 않을 수도 있는 초기 x 값을 모두 고르세요?
(ㄱ) sys.maxint (ㄴ) [1, 2] (ㄷ) 'guido' * 10 (ㄹ) True (ㅁ) sys.version
10. 다음 중 키보드 입력(ctrl-c)으로 중단할 수 있는 것를 모두 고르세요?
(ㄱ) select.select (ㄴ) 9 ** 9999 (ㄷ) os.listdir (ㄹ) Decimal(9) ** 9999 (ㅂ) deque().add
11. CPython VM을 죽일 수 있는 파이썬 코드를 3가지 방법 이상 작성해 보세요.
12. 다음 중 오버라이딩으로 동작을 "바꿀" 수 있는 경우를 모두 고르세요?
(ㄱ) not A (ㄴ) A is B (ㄷ) A = B (ㄹ) A != B (ㅁ) A <- B (ㅂ) A and B (ㅅ) A | B (ㅈ) (A, B)
13. 상속 받은 자식 클래스에서 단순하게 메쏘드를 오버라이드 했을 경우에도 베이스 클래스에서
"강제로" 자기 메쏘드를 부르게 하고 싶을 때 쓸 수 있는 방법 몇 가지?
14. gc.collect()가 해결할 수 없는 문제는?
(ㄱ) 순환 참조 (ㄴ) C모듈의 전역 변수 (ㄷ) C객체의 멤버 변수 (ㄹ) C객체 간의 순환 참조
15. x += y를 실행했는데 ImportError가 발생했다. 어떤 상황일까? 가설을 5개 이상 생각해 보세요.
16. x = y를 실행했는데 TypeError가 발생했다. 어떤 상황일까? 가설을 2개 세워 보세요.
17. if list(x): raise SystemExit 했더니 프로그램이 종료했다. 어떤 상황일까? 가설을 5개 세워 보세요.
18. def x(a, b):에 대해서 x(1, 2)했는데 TypeError가 난다. 어떤 상황일까? 가설을 5개 세워 보세요.
19. import os; os.listdir('.') 했더니 AttributeError가 난다. 어떤 상황일까? 가설을 3개 세워 보세요.
20. print x하면 0인데 if x: print "Yay!" 하면 Yay!한다. 어떤 상황일까? 가설을 3개 세워 보세요.
어제 구글코리아에서 있었던 테크토크 자료입니다.
주제는 "파이썬 - 상상력에 날개 달기"로 C와 자바를 쓰시던 프로그래머들이 자주 갇히게 되는 상상력의 굴레에서 벗어날 수 있게, "헉 이런 것도 되다니!"를 통해서 창의적인 구조를 디자인하는데 도움을 드리는 것이 목적이었습니다.
소개해드리는 소스코드는 각 문제를 해결하는 데 최적의 해결방법이 아니라, 이렇게 하는 방법도 있다는 정도이니 감안해서 참고하시면 좋겠습니다~ (실제로 여기서 사용된 hack을 그냥 막 도입해서 쓰시면 왕따당합니다. ^^*)
얼마 전에 nohmad님 이 소개해 주신AppJet을 보고 파이썬 모듈들을 쓸 수 있으면
무척 좋겠구나! 생각을 했었는데요. 결국 파이썬으로 된게 나왔습니다.
이름은 UtilityMill 대략 우리말로 대장간 정도 되겠습니다~
Zope에서 입력 변수를 웹 UI에서 편집하면 주석에다 달아주듯이, Utility Mill에서는 주석에 달지는 않지만, 양식에 들어갈 변수들의 성질만 정해주면 자동으로 웹 양식을 만들어줍니다. 파이썬 프로그램에는 그냥 전역변수로 들어오기 때문에 그냥 쓸 수 있고, 출력은 print하면 됩니다. 간단!
저도 간단하게 테스트를 해 보려고 예전에 만들었던 한국어 lorem ipsum의 라틴어-한글 변환기 부분을 집어 넣어 보았습니다. 뭔가 처음엔 이상한 에러가 났었는데, 어딘가 고치다보니 저절로(?) 고쳐져서 잘 돌아가는군요;
그러나, 그냥 단순한 프로그램만 돌리면 아무래도 파이썬의 매력은 다 살리지 못한 것일텐데, 여기서는 파이썬의 표준 라이브러리 "전부"뿐만 아니라, BeautifulSoup, numpy, PyCrypto, feedparser, pyparsing, PyRSS2Gen, ReportLab, SciPy 까지도 지원하기 때문에, 정말 간단한 도구들은 웬만하면 불편없이 만들 수 있군요. 웹을 긁어와서 작업하는 것도 가능하기 때문에, 앞으로 아이디어가 생기면 저기에 올려놓고 모두 같이 쓸 수 있게 해야겠습니다. ^-^*
지난 달에 봤던 뮤지컬 《헤어스프레이》가 너무 좋아서 마지막 회차 공연 때 또 보려고 3차 티켓 오픈 소식을 들으려고 웹페이지를 감시하고 있었습니다. 아 그런데 예약페이지를 Update Scanner로 감시해 놓으니까, 정작 보고싶은 예약가능일 변경은 잘 안 보이고, 사이트 전체 예약순위 같은 것만 보이고 그래서, 아 이럴 때 RSS가 있었으면! 하고 무척 답답했었는데요. 그래서 결국 뭔가 다른 방법이 없을까 찾다가 인터파크 티켓 공지사항에 티켓오픈 며칠 전에 공지가 올라온다는 것을 알고 저걸 변경사항 보려니 그것도 좀 그래서 예전에 까나리님 블로그에서 본 적 있는 RSS 자동 만들어주기 사이트가 생각났습니다.
게시판같은 것을 RSS로 자동으로 만들어 주는 feedity.com을 써 봤는데, 치명적인 문제가 인터파크에서는 공지사항을 <제목> 이렇게 <>로 감싸서 올리는 와중 < >를 그냥 써버려서 태그로 인식되어 feedity에서 다 잘라버리는 것입니다. 그래서 결국 제목에서 중요한 부분만 다 없어지는 효과가;; 그리고 본문 요약이 잘 안 되는지 글 내용도 이렇게 다 빈걸로 올라오고 광고만 떨렁 올라오더군요.
그래서 아 이거 재미있겠다 갑자기 호기심이 생겨서 직접 만들어보자 하고 마음을 먹었습니다. -ㅇ-; 우선 요구사항은
여러 군집 간에서 적당한 기준으로 "게시판 글 목록" 군집을 골라 냄. (여기서는 군집 내 최대 거리, 군집의 크기, 군집 내 링크들의 본문 길이를 기준으로)
골라낸 군집의 링크들의 문서를 모두 가져옴
링크를 2개씩 짝지어서 HTML을 비교해서 차이점이 각 링크의 본문이라고 가정해서 뽑아냄
뽑아낸 본문들과 제목 등을 이용해서 RSS 생성
그렇게 해서 autorss라는 이름으로 하나 만들었습니다. 처음엔 간단할 것 같아서 스크립트 파일 1개로 50줄 안에 끝내야지 했는데, 하다보니 모듈 import가 17개인 거대 스크립트가 돼 버렸네요 --;;
생각보다 잘 돌아네요.. ^.^;; 이제 편하게 티켓 오픈 소식을;;;
다른 RSS 제공해 주지 않는 답답한 사이트를 보고 싶을 때 한번
적용해보세요~ (아직 그렇게 소스가 일반화돼 있지 않아서 좀
고칠 부분이 많을 수도 있습니다. 다른 사이트에는 적용해 보니까 DC인사이드 갤러리에도 그런대로 잘 동작하네요. :)
파이썬 마을에 올라온 질문을 읽다가
답변을 하려고보니, 파이썬을 처음 접하는 분들이 빈번하게 궁금해 하시는 문제인 것 같아서,
좀 더 깊게 후벼파서 글로 만들어 봅니다.
질문의 요지는 아래 소스에서 a~f까지 딕셔너리를 임의로 섞고 싶은데 목록이 많을 수도 있고
자주 바뀌기도 하니까 좀 더 좋은 방법이 없을까 하는 것입니다.
import random
a = {'aa': 1}
b = {'bb': 2}
c = {'cc': 3}
d = {'dd': 4}
e = {'ee': 5}
f = {'ff': 6}
this = [a, b, c, d, e, f]
random.shuffle(this)
print this
이거랑 완전히 똑같은 상황이 자주 일어나지는 않겠지만, 그래도 종종 처음엔 네임스페이스에
변수를 왕창 넣어놓고 이걸 어떻게 해보고 싶은 경우가 있긴 하니까 그래도 파이썬 프로그램들이
자주 사용하는 패턴들로 해결해 보겠습니다.
[1] 정면승부! 네임스페이스 직접 접근해서 거시기하기
import random
import inspect
def shufflelocaldicts():
outerframe = inspect.getouterframes(inspect.currentframe())[1][0]
names, objs = [], []
for name, obj in outerframe.f_locals.iteritems():
if isinstance(obj, dict):
names.append(name)
objs.append(obj)
random.shuffle(objs)
for name, obj in zip(names, objs):
outerframe.f_locals[name] = obj
a = {'aa': 1}
b = {'bb': 2}
c = {'cc': 3}
print a, b, c
shufflelocaldicts()
print a, b, c
shufflelocaldicts()
print a, b, c
첫 번째로는 원래 프로그램 자체는 전혀 안 건드리고 그냥 원하는 작업만 하는 방법입니다.
(변수 개수는 소스코드 길이를 줄이려고 3개로 줄였습니다.)
shufflelocaldicts()를 호출하면 바깥 프레임에 접근해서 바깥 네임스페이스의 딕셔너리를 모두
가져다가 섞은 다음에 다시 넣어줍니다.
이건 고칠 부분이 줄기는 하지만, 모든 하이테크 방법들이 그렇듯
깨지기도 쉽고 사용하는 사람들이 제대로 알지 않으면 엉뚱하게 흘러갈 수도 있는 잠재적 위험성이 있습니다.
[2] 구차하더라도 열심히 고치기
import random
shufflers = []
_ = shufflers.append
a = {'aa': 1}; _('a')
b = {'bb': 2}; _('b')
c = {'cc': 3}; _('c')
def shuffledicts():
shuffled = shufflers[:]
random.shuffle(shuffled)
gdict = globals()
values = [gdict[k] for k in shufflers]
for newname, obj in zip(shuffled, values):
gdict[newname] = obj
print a, b, c
shuffledicts()
print a, b, c
shuffledicts()
print a, b, c
두 번째 방법으로 바깥 네임스페이스를 검색하는 흑마법을 쓰지 않고 일일이 등록해주는 것이
있습니다. 이 방법은 일일이 등록해야한다는 것이 약간 중복의 냄새도 있긴 하지만, 단순하고
잘 작동하고 명시적이라서 잘 보인다는 점에서 상당히 자주 사용되는 패턴입니다. 그렇지만 역시
이 경우에는 그다지 썩 좋지는 않네요.
[3] 좀 머리를 굴려보자
import random
import inspect
a = {'aa': 1} # !SHUFFLE!
b = {'bb': 2} # !SHUFFLE!
c = {'cc': 3} # !SHUFFLE!
shufflers = [] # !SHUFFLELIST!
def generate():
import re, StringIO
pat_entry = re.compile(r'^([A-Za-z0-9_]+).*#.*!SHUFFLE!$')
pat_slist = re.compile(r'^([^[]+)\[[^]]*\](.*#.*!SHUFFLELIST!)$')
srcout = StringIO.StringIO()
names = []
for line in open(__file__):
entry = pat_entry.match(line)
if entry:
names.append(entry.groups()[0])
slist = pat_slist.match(line)
if slist:
head, tail = slist.groups()
print >> srcout, '%s[%s]%s' % (head, ', '.join(map(repr, names)), tail)
else:
srcout.write(line)
open(__file__, 'w').write(srcout.getvalue())
def shuffledicts():
shuffled = shufflers[:]
random.shuffle(shuffled)
gdict = globals()
values = [gdict[k] for k in shufflers]
for newname, obj in zip(shuffled, values):
gdict[newname] = obj
def run():
print a, b, c
shuffledicts()
print a, b, c
shuffledicts()
print a, b, c
if __name__ == '__main__':
print "Regenerating the source code.."
generate()
이번에는 노장 프로그래머들이 동적 언어들이 그렇게 활발하기 전에 예전에 자주 사용했던 방법으로,
태그를 보고 코드를 자동생성하는 방법입니다. 요새도 전혀 사용되지 않는 것은 아닌데, 프로그램이
변경될 때마다 스크립트를 한 번씩 실행해 주면 자동으로 소스의 주석을 보고 [] 사이의 빈칸을 채워줍니다.
이 기법은 파이썬 프로그램보다는 C프로그램에서 보통 유용하게 쓰이는데요,
cog같은 툴들을 쓰면 좀 더 간편하게 할 수 있습니다. 이건 뭐 대체로 잘 작동하기는 하지만, 어쩌다
소스코드 업데이트가 빠지면 재앙이 생기기도 하고, 그다지 멋지지 않다는게 좀 흠입니다. 주석에 의존한다는게
특히 좀 찝찝하죠. -o-
[4] 객체지향 좀 배운 사람인 척 티내보기
import random
class ListItemProxy(object):
def __init__(self, obj, idx):
self.__obj = obj
self.__idx = idx
def __getattr__(self, name):
if name.startswith('__'):
return self.__dict__[name]
else:
return getattr(self.__getobj__(), name)
def __repr__(self):
return repr(self.__getobj__())
def __getobj__(self):
return self.__obj[self.__idx]
def __setitem__(self, name, value):
return self.__getobj__().__setitem__(name, value)
def __getitem__(self, name):
return self.__getobj__().__getitem__(name)
def __detitem__(self, name):
return self.__getobj__().__detitem__(name)
deck = [{'aa': 1}, {'bb': 2}, {'cc': 3}]
a = ListItemProxy(deck, 0)
b = ListItemProxy(deck, 1)
c = ListItemProxy(deck, 2)
print a, b, c
random.shuffle(deck)
print a, b, c
random.shuffle(deck)
print a, b, c
앞에서 썼던 방법들은 직관적이고 단순하기는 해도
역시 너무 무식한 방법같은 냄새가 납니다.
이번엔 파이썬에서 객체 꽁수를 배우고 한참 기분낼 때 아주 재미있게 하는 객체 오버라이딩으로
위임(proxy) 객체 만들어주기입니다. 대형 프로젝트에서는 이런 스타일을 종종 사용하기도 하지만,
짧은 스크립트에서 쓰면 좀 격에 안 맞기는 하죠. 직접 딕셔너리를 만들어서 그걸 어쩌고 저쩌고하는
대신에 리스트에 원래 걸 넣어두고 그 첫번째, 두번째~ 등을 간접적으로 작업을 지원해 주도록 하는 방법입니다.
이 방법은 shuffle이 매우 빠른 게 장점이고, 참조가 리스트 하나 안에 모여서 깔끔하게 정리가 돼 있는게
좋습니다. 그런데 문제는 역시 위임이 중간에 거치기 때문에 속도상 불이익이 있고, 위임을 제대로 하려면
위 소스보다 훨씬 길게 짜야 한다는 거겠죠.
[5] 딕셔너리들을 모두 관리하는 오버마인드
import random
class sdict(dict):
alldicts = []
def __init__(self, *args, **kwds):
dict.__init__(self, *args, **kwds)
self.alldicts.append(self)
@classmethod
def shuffle(klass):
dicts = []
for d in klass.alldicts:
dicts.append({})
dicts[-1].update(d)
d.clear()
random.shuffle(dicts)
for d, o in zip(klass.alldicts, dicts):
d.update(o)
a = sdict({'aa': 1})
b = sdict({'bb': 2})
c = sdict({'cc': 3})
print a, b, c
sdict.shuffle()
print a, b, c
c['rr'] = 9
sdict.shuffle()
print a, b, c
이번엔 딕셔너리 자체를 상속받아서, 2번에서처럼 따로 등록하는 대신 딕셔너리 초기화 도중에
자동으로 등록되게 하고, 4번처럼 위임을 구질구질하게 하지 않고도 자체가 그냥 딕셔너리가 되게 했습니다.
요것도 어느 정도 장점이 있긴 하지만, 역시 딕셔너리를 만들 때 마다 일일이 캐스팅을 해 줘야하고,
원래 객체의 참조를 건드리려면 역시 이름 없이는 할 수 없기 때문에, 참조를 놔둔채로 내용을 바꾸기 위해서
내용을 싹 비워서 다른데 옮겼다가 다시 부어주는 좀 심각하게 비싼 작업이 들어가는게 단점입니다.
[6] 억지로 구겨넣지 말고 원래 모양을 바꿔보자
import random
class ShuffleDeck(object):
def shuffle(self):
names = self.__dict__.keys()
random.shuffle(names)
for k, v in zip(names, self.__dict__.values()):
self.__dict__[k] = v
deck = ShuffleDeck()
deck.a = {'aa': 1}
deck.b = {'bb': 2}
deck.c = {'cc': 3}
print deck.a, deck.b, deck.c
deck.shuffle()
print deck.a, deck.b, deck.c
deck.shuffle()
print deck.a, deck.b, deck.c
앞에서 썼던 여러 구질구질한 방법들은 결국 네임스페이스에 흩어져 있는 것들을 어떻게든
관리를 하려다보니 생기는 문제입니다. 그냥 네임스페이스에 흩어지지 않게 따로 모아두면
결국 그렇게 고생 안 해도 간단하게 해결됩니다. 굳이 __dict__를 쓰지 않더라도 그냥 리스트에
번호붙여서 넣어서 쓰거나, 다양한 깔끔한 방법이 네임스페이스에 흩어놓는 것만 포기하면
마구 생겨납니다.
결국은!
이 경우에 우선 문제를 해결하려다보면 앞에서 소개해 드렸던 다양한 방법으로 억지로 해결할 수도 있습니다.
다 만들어 놓은 프로그램을 막판에 약간 어떻게든 고쳐서 출시를 해야하는 경우나, 당장 여자친구가
얼른 안 오면 삐진다고 문자를 수십통을 보내고 있는데 과장님은 얼른 고쳐내라고 옆에서 1분마다 보채고 있을 때
뭐 이런 극한 상황에서나 얼른 쓰고 도망갈 때 쓸만한 방법이겠죠;
역시 이 문제의 경우에는 질문 자체의 요구사항을
파이썬에서 쉽게 해결할 수 있는 방법으로 바꾸는 게 중요합니다. 딕셔너리 여러개를 마구 섞는 문제라고 최종 문제를
보면 상상력의 한계가 있지만, 그것보다 원초적으로 다뤄야하는 문제를 보면 딕셔너리를 여러개 마구 섞는게
아니라 간단하게 해결할 수 있는 다른 자료구조가 반드시 있을 것 같은 예감이 강렬하게 드는군요. -O-; (그리고 마지막으로 하나 덧붙이고 싶은 것은, 생각보다 원래 질문의 코드도 보기에는 좀 그렇더라도 복잡한 방법을 안 썼다는 점에서 그런대로 쓸만한 코드입니다. 물론 문제 자체를 바꾸는게 더 좋을 것 같긴 하지만요;)
Summer of Code를 여러 해 동안 성공적으로 운용해오고 있는
구글에서 드디어 얼마 전, 고등학생을 위한 행사를 공개했습니다.
이름은
The Google Highly Open Participation Contest이고,
대상은 13세 이상이고 대학이전의 학교(한국에서는 초,중,고등학교)에 다니고 있는 사람입니다. 그리고, 북한에 사는 학생들은 참가가 제한됩니다. -O-
그동안 SoC가 대학생이 주 대상이었는데, 실제로 요즘은
고등학생들이 꽤 많이 참가하고 있고, 앞으로 오픈소스 새싹을 키우려면 (상투적이지만;;) 중,고등학생이 프로젝트에 적극적으로
참여할 수 있는 이런 기회가 생겨서 무척 좋습니다.
파이썬 재단의 GHOP 목록을
보면 그다지 어렵지 않으면서도 파이썬의 중요한 부분에 재미있게
참여할 수 있는 여러 작업들을 가지고 있어서 중고등학생이
오픈소스 프로젝트의 마수에 걸려들게 하는 좋은 미끼일 것 같군요. :-)
구체적인 형식은 Summer of Code와는 많이 다른데요, 큰 프로젝트를 멘터와 함께 만들어서 제안하는 방식이 아니라, 일정기간
(2007년 11월 27일부터 2008년 2월 3일까지)동안 이뤄낸 작은
작업들에 대해 보상을 받습니다. 쿠폰바꾸는 것과 비슷한데요, 도장 1개는 24달러짜리 티셔츠를 받을 수 있고, 3개는 100달러를 현금으로 받을 수 있습니다. 1인당 티셔츠 1개 + 500달러 현금으로 최대 상금이 제한되어있습니다.
구체적인 규칙은 GHOP 2007-8 Rules에 나와 있습니다. 우리나라의 열의 넘치는 중고등학생들이 많이 참가해서 다음 행사에 티셔츠 우루루 입고 참가하면 좋겠네요~ :)
bisect
모듈은 정렬된 list에서 이진검색법으로 자료의 위치를 찾아줍니다.
dict로 다루기에는 자료의 양이 많거나, 순서가 중요한 경우에 쓸만합니다.
아래 예제는 동전을 몇 번 던지면 앞면이 나오나 같은 경우를 나타내는
기하분포 랜덤함수를 bisect로 만든 방법인데, 그냥 계산해버리는
방법도 있지면 예제를 위해서 --; (실제로 분포함수가 없고 그냥 이산확률만
덩그러니 주어졌을 때 bisect가 꽤 쓸만합니다.)
별로 관심있는 분들이 없는 것 같아서 다음 편을 안 쓰고
있었는데, 오늘 어딘가에서 모듈 관광을 읽었다는 분을 만나고
어딘가에는 읽는 분이 있구나! 싶어서 생각난 김에 한 번 또 씁니다;
오늘의 모듈은 durus 입니다. 이미 SCGI같은 여러 프로그램들로 유명한 CNRI MEMS-Exchange 팀에서 만들었습니다. 원래 파이썬 뿐만 아니라 다양한 환경에서 캐시 공유나 분산 배치 작업 같이 한 데이터 공간을 여러 프로세스가 써야하는 경우에는 memcached가 거의 압도적으로 많이 쓰이는 솔루션이겠지요. durus는 이와 비슷한 역할과 표준 shelve의 기능이 모두 필요한 경우에 요긴하게 쓸 수 있습니다.
미리 서버를 띄워두고.
cysteine(perky):~% durus -s
Storage file=/tmp/tmpzRHYiQ address=127.0.0.1:2972
Ready on 127.0.0.1:2972 with 0 objects
시험삼아 접속해서 UUID 객체를 하나 넣어봅니다.
cysteine(perky):~% python
Python 2.5.1 (r251:54863, Nov 5 2007, 09:29:15)
[GCC 4.2.1 20070719 [FreeBSD]] on freebsd7
Type "help", "copyright", "credits" or "license" for more information.
>>> from durus.client_storage import ClientStorage
>>> from durus.connection import Connection
>>> c = Connection(ClientStorage())
>>>
>>> import uuid
>>> c.root['uuid'] = uuid.uuid1()
>>> c.commit()
>>>
이렇게 되면 서버에 커밋되었다는 메시지가 보입니다.
Committed 1 objects 147 bytes at 2007-11-26 20:03:52.203449
이제 다시 클라이언트를 따로 띄워서 접속해서 확인해 봅니다.
cysteine(perky):~% python
Python 2.5.1 (r251:54863, Nov 5 2007, 09:29:15)
[GCC 4.2.1 20070719 [FreeBSD]] on freebsd7
Type "help", "copyright", "credits" or "license" for more information.
>>> from durus.client_storage import ClientStorage
>>> from durus.connection import Connection
>>> c = Connection(ClientStorage())
>>> c.root['uuid']
UUID('4353180c-9c0f-11dc-bffd-0001028cad3c')
역시 MEMS Exchange에서 만들었던 다른 작품들과 같이 기능도 괜찮으면서 단순해서 속도도 쓸만합니다. 여러 프로세스가 협업하거나 임시로 떴다 죽었다 하는 프로그램들에서 객체를 다뤄야할 때 쓰면 좋겠네요. :)
지난 번 모듈 관광 1회의 뜨거운 성원에 힘입어 (;;)
2회를 준비했습니다. 으흐흣~
오늘은 역시 초기이니, 많이 안 알려진 것을 일부러 골라 봤는데요.
파이썬 표준라이브러리에 들어있지만 문서화가 안 되어 있고
책에서도 좀처럼 소개해주지 않기 때문에, 쓰는 곳도 찾기
힘든 그런 모듈로 이름은 imputil 입니다.
파이썬에서는 임포트 과정을 직접 조작할 수 있는데, 그 기능을
이용한 것이 대표적인게 바로 zipimport 모듈입니다. 그 덕분에
파이썬에서는 모듈을 zip에 묶어놔도 읽어들일 수 있게 되어
있는데요. 이 과정을 직접 만들려면 파이썬 내부 동작을
건드릴 부분이 많다보니 귀찮은 과정을 겪어야합니다.
이런 과정을 파이썬 언어스럽게 간단하게 해결할 수 있게
대충 껍데기를 만들어 놓은 것이 바로 imputil입니다.
관광에서는 역시 복잡한 걸 해 보면 안 되니까, 간단하게
파이썬 프로그램 확장자를 .py가 아니라 .pl인 것도 읽을
수 있게 고쳐봅시다. (-O-;;) 우선 foo.pl 라는 이름으로 파일을
만듭니다.
플러그인에 괜히 자기 프로그램 이름을 붙여서 파이썬 아니고
뭔가 특별한 것인 척 할 때 좋겠죠? :) 괜히 암호화해 놨다가 풀면서 임포트하게 할 수도 있고.. 여러가지 응용이 가능하겠습니다.
--- (플러그인 프레임워크를 위해 제어할 때는 마찬가지로 표준 모듈인 imp를 쓰면 멋있게 만들 수 있습니다.)
요새 블로그가 있다는 존재를 스스로 까먹을 정도로 안 썼더니만
뭔가 블로그 들어오기가 무서워서, 연재물을 하나 구상했습니다.
예전에 회사에서 한번 옆 사람한테 "모듈 관광"을 한번 시켜줬더니
좋아하길래 블로그 버전으로 모듈의 용도와 특징만 겉핥아보는
모듈관광 연재를 해 보려구요!
첫 관광명소(?)로 뭐가 좋을까 한참 고민을 하다가, 아무래도
첫회이니만큼 너무 잘 알려진 모듈을 하면 보는 분들이
지루하지 않을까 싶은 생각이 들었습니다. 그래서 결국 아무도
모를만한(;;) 모듈을 찾아봤는데 뭐 사실 인터넷에 다 있는데
아무도 모를리야 없을테고 그래도 잘 안 쓰지만 저는 매일매일
쓰는 모듈을 하나 건져 올려 봤습니다. :)
처음으로 소개해 드릴 모듈은 "ezpyinline"이라는 모듈인데,
이름에서 풍기듯 "쉽게 파이썬에 C를 인라인"할 수 있는 모듈입니다.
이런 건 전에도 몇 번 나오기는 했지만, 그래도 보통 시대 흐름에
따라서 요구사항이 달라지는데 오래 전에 나온 것은 스타일도 다르고
여러모로 취향이 다르니까 새것이 유지만 잘 되면 쓰기는 편할 것 같네요.
인라인 같은 요구사항이 있을 때는 보통 C로 간단하게 인터페이스를
줄인 다음에 pyrex를 쓰거나, SWIG같은 래퍼를 쓰거나, 아니면 직접 다 모듈을 짜버리는 방법이 정통적인 방법입니다.
간단한 것 할 때는 뭘 해도 상당히 귀찮죠. 파이썬은 역시 기동성이 힘! ez붙은 건 거짓말만 아니라면 다 한번씩은 봐 둘 가치가 있겠죠;
관광에 설명이 너무 많으면 안 되니 경치구경으로 대신합니다. :)
>>> import ezpyinline
>>> cfactorial = ezpyinline.C(r"""\
... int factorial(int v)
... {
... int i, r = 1;
... for (i = 2; i <= v; i ++) r *= i;
... return r;
... }""").factorial
>>> cfactorial(1)
1
>>> cfactorial(12)
479001600
진정 보람을 느끼려면 항상 예전과 비교를.. ^.^
>>> def pyfactorial(v):
... return reduce(lambda x, y: x * y, range(2, v+1), 1)
...
>>> def mytimeit(f, *args):
... st = time.time()
... for i in xrange(1000000):
... f(*args)
... return time.time() - st
...
>>> mytimeit(cfactorial, 12)
0.39980006218
>>> mytimeit(pyfactorial, 12)
5.71780800819
대략 10배 넘게 성능 향상이 있었습니다. 와우~! (뻔한 일에도 감동을;)
그래도 아무래도 타입이 조금만 복잡해져도 자동 처리가 난감해지고 하는 면이 있기 때문에,
아주 인터페이스를 단순화해서 임시 실험용으로 쓸 코드에서
C코드로 가속을 하고 싶을 때 유용할듯 합니다.
파이썬계에서 8월은 파이썬 3000으로 열기가 가득한 한 달이었습니다. 8월 초에 드디어 문자열의 유니코드화 작업이 완료돼서 py3k 브랜치로 머지되었고, 새 I/O 스택도 거의 제 모습을 갖췄습니다. 그리고, 약속을 지키기 위해 드디어 8월 31일(미국 서부시간 기준), 파이썬 3.0a1이 릴리스될 예정입니다.
최근의 변화를 보자면, 문자열 유니코드화는 이미 다른 곳에서 많이 보셔서 지겨울 정도이고, 최근 논란이 많았던 str.format이 얼마 전에 구현이 완료되어서 들어갔습니다. str.format이 그동안 파이썬의 마스코트(?)같았던 존재인 문자열 % 연산자를 대체할 예정입니다.
그동안 파이썬에서 행렬 계산은 Numeric/NumPy, 기타 과학 연산은
SciPy 등 속도가 필요한 분야에 대한 해결책을 대체로 제시하고 있었지만
동적계획법(Dynamic Programming)이나 몬테카를로 시뮬레이션 같이 비교, 분기가 대량으로
발생하는 경우 파이썬만 가지고는 도저히 어떻게 해 볼 수 없는 한계가 어느 정도 있었습니다.
Pyrex는 뭔가 좀 답답하고 Psyco는 썩 만족스러운 단계까지
올라가지도 않고, 결국에 눈물을 머금고 C로 주요 코드를 짤 수 밖에 없었습니다.
그래서 몇 군데에서 시도했던 것이 파이썬에서 직접 어셈블리 코드를 실행시간에 생성해서
실행할 수 있는 JIT 어셈블러들이 등장했었는데요. 파이썬 코드랑 어셈블리랑 어색하게 결합하고
있다보니 인라인 어셈블리쓴 C보다 훨씬 더 어색해서 별로 쓰기가 유쾌하지는 않았지요.
합성 프로그래밍 환경(SPE)는 이걸 좀 더 우아하게 해결해보려는 라이브러리 입니다.
OpenSSL에서 사용하는 perlasm같이 스크립트 언어의 자체 문법으로
약간은 추상화된 방법으로 명령을 작성하면, 그 코드가 실행되면서 어셈블리 코드가 생성되고
그게 결국 실행되는 방법입니다. 너무 추상화하면 C나 다름 없으니, 거의 1:1로 맞춰볼 수 있을 정도로
간단하게 처리했지만, 사실 "합성(synthetic)"이란 말에서 드러나듯, 파이썬 문법에 대체적으로
끼워넣어서 재사용성을 매우 높일 수 있다는 점이 장점입니다.
간단한 perlasm에서도 풀어쓰기(unroll)이나 스택 셋업, 인수 대량 전달, 디버그 출력,
클린업 같이 많은 작업들을 라이브러리화 해서 쓰고 있어서, 실제 생성되는 최종 어셈블리 코드보다
훨씬 사람이 보기 쉽고 재사용할 수 있는 코드를 씁니다. SPE에서는 perlasm에서 쓰는 것 뿐만 아니라
벡터연산을 훨씬 쉽고 간단하게 쓸 수 있게 해 주기도 하고, 간단하고 단순노동적인 조건문이나
오프셋 계산 같은 것들을 우아하고 보기 쉽게 쓸 수 있도록 해 줍니다. 게다가 파이썬 코드
안에서 섞어 쓸 수 있기 때문에, 귀찮게 왔다갔다 할 필요도 없습니다.
결국, SPE의 모토는 "Skipping C"라고 하는데, 두 가지 의미가 있습니다. 하나는 원래 파이썬이
C언어로 된 인터프리터, 익스텐션 라이브러리, 컴파일러 등을 통해서 기계어로 실행(+번역)되어
왔는데, 이를 건너뛰어서 그냥 파이썬에서 바로 기계어를 쓰자는 의미로 볼 수 있고,
나머지 하나는 개발할 때 C언어로 개발할 필요를 많이 줄여서 C는 쓰지 말자 뭐 이런 의미로
볼 수도 있겠죠. 즉, 평소같으면 C로 상당수 기반을 만들어서 파이썬에서 사용하는 방식을 채택할
경우라도 파이썬과 SPE에서 제공하는 어셈블리를 쓰면 C 안 쓰고도 비슷하거나 빠른 속도를
낼 수 있다는 얘기입니다.
많은 분들이 이쯤 되면, 속도가 상당히 궁금하실텐데, 간단하게 1000만까지 숫자를 더하는 프로그램을
작성했을 때, 파이썬으로 작성된 코드가 3.64초, 내부 코드 및 자료구조가 모두 C로 작성된
NumericPython으로 0.054초, SPE로 0.019초라고 합니다. (SIMD는 사용하지 않음)
요새 C 컴파일러가 좋긴 하지만, 사람은 알고리즘까지도 변경하면서 최적화할 수 있고, 굳이
프로파일링 하지 않고도 어느 정도까지는 분기 수요를 예측할 수 있다는 점 때문에
아무래도 같은 시간 노력하면 짧은 코드는 SPE로 하는 어셈블리가 C보다 이렇게 빠를 수 있지 않을까 싶군요.
(물론, 요새 유행하는 프로파일링 컴파일러를 빡시게 돌리면 C나 SPE나 결국 비슷한 최고속도에 도달하겠지만요.)
SPE가 주 대상으로 하는 것은 아무래도 과학계산과 멀티미디어 연산이 되겠지만, 사실 과학연산에서
어셈블리를 다룰 정도로 컴퓨터 구조에 대한 지식이 있는 연구자의 수가 그렇게 많지 않은 것을 생각해 보면
기계 지식없이도 어셈블리를 쉽게 할 수 있게 라이브러리가 많이 확충되어서 "합성"만 해도 프로그램이 되면 아주 좋겠네요.
물론, 파이썬에서 도저히 어떻게 해결할 방법이 없던 한가지 프로그램 주제를 비교적 깔끔하게 해결해버렸다는
점에서는 벌써 상당한 가치가 있는 시도로 보입니다.
(참고사항: SPE의 구현인 CorePy는 현재 PowerPC만 지원하고 있고, 라이선스도 오픈소스가 아니라 시험용으로만
사용할 수 있는 라이선스이기 때문에, 이걸로 당장 뭔가 해 보기는 힘듭니다. :)
그동안 파이썬의 euc-kr 코덱에서는 KS X 1001 완성형에 들어있지
않은 글자는 그냥 에러로 처리해 왔습니다. GNU libiconv나 GNU libc를 포함한
대부분의 오픈소스 프로그램들도 그냥 완성형만 지원해 왔었는데요.
얼마전에 MSIE에서 어떤 상황에서 EUC-KR에서도 첫가끝 코드를 활용하는 사례가 보고되었고, 모질라에서도 2001년부터 이미 첫가끝을 지원하고 있었습니다.
그래서, 파이썬에서도 뭔가 그래도 부록이지만 표준 문서에 있긴 있는 내용이니 지원해야겠다 마음이 들어서, EUC-KR 코덱에 새로 구현하여 넣었습니다. 코덱 이름은 바뀌지 않고 그대로 euc_kr 이기 때문에 사용상 별로 다른 점은 없고, 완성형만 걸러내기 위한 목적으로 쓰셨던 분들은 이제부터 다른 방법을 쓰셔야 됩니다.
약간 늦은 감은 있지만, 오늘 드디어 파이썬 2.5.1이 디폴트로 바꾸었습니다.
그동안 2.4.4로 쓰느라 여간 답답하지가 않았는데, 7개월 정도에
걸쳐서 띄엄띄엄 작업해서, 오늘 겨우 넣었네요. 이른바 메가커밋!
지난번 버전까지는 저 혼자 모든 파이썬 관련된 작업을 했었는데,
이번 버전부터는 python@ 팀을 꾸려서 다른 팀원들과 함께 하고
있습니다. 처음에는 팀원들 중에 커미터가 아닌 사람도 몇 있었는데
워낙 기근에 허덕이는 커미터 구인난 때문에, 어느새 다 커미터가
돼 버렸네요. -o-;
파이썬 2.5가 나오고 벌써 9개월이나 지난 후에 된 것이라 지난 버전들보다 엄청 늦음에도 불구하고, 우분투 리눅스를 제외한 다른 오픈소스 시스템들에서는 여전히 2.4인 것을 보면, 2.4가 굉장히 만족스럽거나, 이제 파이썬 버전이 올라가도 그다지 개발자들 관심을 안 끌거나.. 지난 업데이트와는 좀 다른 것 같네요. NetBSD나 OpenBSD같은 경우에도 아직 2.4를 쓰고 있구요.
작업 도중 가장 힘들었던 것이, egg-info 문제인데, 갑자기 모든 distutils 패키지들이 엉뚱한 파일을 하나씩 다 설치하는 데 파일이름이 제각각이어서 수동으로 지정하는 방법 밖에는 없었습니다.
그래서 1000개에 달하는 파이썬 관련 패키지에 수천에 달하는 의존성 패키지를 다 가져다가 빌드해서 설치하는 파일 이름을 얻은 다음 그걸 적용하는 바람에 이번에 패치된 파일이 444개입니다.
총 7번의 포트 클러스터 빌드를 통해 검증한 덕에, 최종적으로 커밋된 포트에서는 초기에 발생했던 1000개 이상의 문제가 대부분 수정되었습니다.
그리고, Py_ssize_t 문제도 빠질 수가 없는데요, 파이썬 2.5부터 원래 int로 사용하던 크기 관련 변수들이 모두 Py_ssize_t로 바뀌는 바람에 amd64 같은 아키텍처에서 API가 안 맞아서 빌드하다가 죽거나 심지어 설치 다 하고 돌아가다가 죽는 문제가 발생했습니다. 가능한 한 많은 테스트로 수정을 하기는 했지만, 여전히 몇몇 패키지에서는 문제가 남아있는 것 같네요. 앞으로 보고되는대로 수정할 계획입니다.
이번 업데이트에서 (포트 측면에서) 수정된 사항들은 다음과 같습니다.
egg-info 지원 추가: 파이썬 2.5부터 distutils로 설치되는 모든 프로그램들이 egg-info파일을 설치합니다. egg-info 파일의 경우 웬만하면 고칠 일은 없지만, 필요한 경우 PYDISTUTILS_PKGNAME과 PYDISTUTILS_PKGVERSION으로 조절해서 이름을 맞춰줘야 합니다.
easy-install 지원 추가: 그동안 django를 필두로 해서 수많은 웹 관련 패키지들이 setuptools를 도입해 왔는데, 이번에 포트 전역적으로 setuptools지원이 추가되었습니다. USE_PYDISTUTILS= easy_install 로 적어주면 자동으로 egg위치 같은 것이 처리됩니다. pkg-plist에서는 %%PYEASYINSTALL_EGG%%로 해주면 egg 이름이 대체됩니다.
디폴트 버전 마음대로 선택 가능: 지금까지는 포트에서 지정하는 버전 한 가지만 디폴트로 쓸 수 있었지만, 이제 PYTHON_DEFAULT_VERSION을 /etc/make.conf에 지정해서 디폴트 버전을 바꿀 수 있습니다. 아무리 세상이 바뀌어도 나는 무조건 2.3을 디폴트로 쓰겠다 하시는 분들도 편하게 2.3을 디폴트로 적용할 수 있습니다. 대부분의 경우에는 자동인식 되기 때문에 따로 설정할 필요는 없습니다.
요새 인텔에서 80코어 CPU를 공개할 정도로 점점 병렬 프로세싱이 싼 가격과 작은 크기로 내려올 것 같은 분위기가 많이 돌고 있습니다. 저도 요즘 학교에서 하는 실험이 CPU 20개에 분산해서 실행해도 하루 정도 돌아가는 것이다 보니, 컨커런트 프로그래밍이 기본적으로 지원되는 언어들에 대한 소식에 요즘 상당히 솔깃 하고 있는데요. 으흐흐 하여간 파이썬은 GIL 때문에 여러모로 불안할 따름입니다;
긴 시간이 걸리는 같은 종류의 작업을 여러 데이터에 적용하는 경우를 가정하고 만든 것인데요, 우선 용례를 보면 이렇게 하면 좋겠다 생각이 들었습니다.
import random, time
from procutil import parallelize
WORKS = range(101, 110)
for work in parallelize(4, WORKS):
print "Starting work", work
random.seed(hash(work))
time.sleep(random.random() * 6 + 5)
print "Work", work, "finished"
print "Done"
보통 이런 것들은 threads.start_new_thread()처럼 뒤에 함수를 줘서 그게 실행되는 경우가 많은데, 그러면 조그만 작업도 다 함수로 만들어야 해서 코드가 왔다갔다 해서 헷갈리죠. 그래서 for루프 안에 넣었는데, 실제로 for 안쪽이 여러 번 돌지는 않고, 각각이 별도의 프로세스로 최대 4개가 동시에 돌아가게 됩니다. 그래서 이 인터페이스에 맞게 구현해 보면 요렇게..
이렇게 만들고 나니, 왠지 결과 데이터를 메인 프로세스에 모두 모아오는 기능이나 프로세스 재활용 같은 기능도 넣어 보고 싶고 with 절로 해 보고 싶기도 했지만.. 일단은 돌아가기에 귀찮아서.. 흐흐 -ㅇ-;; with로 하는 경우에는 for와는 다르게 메인 프로세스에서 하위 블럭을 생략할 수 없어서 메인 프로세스도 일을 해야하다보니 좀 더 복잡하겠더군요..
그런데, 사실 이걸로 열심히 놀고보니, 원래 쓰던 셸 스크립트로 하는 방법이 훨씬 간단한 것 같아서 허탈합니다. 하하;;;; ㅡ.ㅜ
그동안 파이썬에서는 변수 이름, 함수 이름, 클래스 이름 등등에서 영문 알파벳과 숫자, 밑줄만 사용할 수 있었습니다.
전문 개발자들이야 영어가 필수이다보니 그냥 쓰면 된다지만, 어린 애들이나 도구로 프로그래밍을 하는 분들은
영어로 써야한다는 것이 엄청난 어려움으로 다가올 수 밖에 없습니다. 주석을 변수이름에 녹인다는 기법만 적용하려고
해도, 주석은 한글로 쓸 수 있다지만 변수 이름을 한글로 쓰지 못하면 녹여내지 못하고 결국 초딩용 코드 a, b, c가
등장하게 돼서 암호가 돼 버리죠 =.= 그래서 그동안 비영어권 국가 개발자들은 유니코드 식별자의 필요성을
계속 얘기하고 있었고, 한국, 중국, 일본 같은 경우에는 각각 비영어 식별자를 지원하는 패치를 배포하기도 했습니다.
그러던 중, Python3000을 위해 논의되어 왔던 파이썬 비-아스키 식별자 (non-ASCII identifier)가 지난 5월 27일에 드디어 통과되었습니다.
오랫동안 거의 "내 눈에 흙 들어가기 전에는..." 수준으로 비-이스키 식별자 (밑에서는 유니코드ID로 표기)를
싫어하던 귀도가 그동안 내 아들들에게도 자국어로 프로그래밍할 수 있는 기회를 주고 싶다는 마틴, 발터 등의
여러 비영어권 개발자들의 노력으로 설득당해버렸군요. :) (물론 이 뒤에는 무려 메일 1000개가 넘는
여러가지 기술/정책/정치적인 토론이 있었습니다.)
아직 PEP에서는 상세하게 다뤄지지 않았는데, 일단은 PEP번호는
PEP-3131입니다. (이렇게 내용 없는 PEP가 accept되기는 처음이 아닐까 싶은데, PEP로 정리만
되지 않았지 토론 내용 여기저기에 충분히 의견의 합의는 있었습니다.)
그럼, 한중일에서 그냥 2~3줄 패치해버리는 것으로 간단하게 됐던 한글 허용을 도대체
파이썬에서는 무엇때문에 이렇게 논란이 많은지 고민하실텐데요, 모든 문제의 원천은
소스파일마다 인코딩이 다른 상황 때문에 발생합니다. 소스코드끼리 인코딩이 다를 때
서로를 참조하는 방법을 통일시키려면 시스템 내부의 인코딩을 통일할 수 밖에 없는데,
이것으로 유니코드를 채택하다보니 유니코드에서 발생하는 여러가지 특징들이 문제로 다가오게 됩니다.
한중일의 패치는 그냥 허용 영역만 푼거라서, 사실 이런 것에 대해서는 대책없이 그냥 임시방편으로
풀어놓았던 것이지요.
대표적인 문제를 보자면, 우선 정규화(normalization)문제가 있습니다. 정규화는 똑같은 논리적
글자가 유니코드에서 여러가지 방법으로 표현되기 때문에 발생하는 문제인데, 예를 들어서
한글의 경우에는 "한(U+D55C)"과 같이 완성형으로 표현하는 방법도 있고, "ㅎㅏㄴ(U+1112 U+1161 U+11AB)"같이 조합형으로 풀어서 쓰는 방법이 있습니다. 앞과 같이 최대한 뭉쳐서 표현하는 방식을
NFC(Normalization Form C)라고 부르고, 뒤와 같이 최대한 풀어서 표현하는 방식을
NFD(Normalization Form D)라고 부릅니다. 둘 중 하나로 표현하면 논리적으로 같은 글자가
코드로도 똑같이 표현이 되니까, 코딩 방식을 다르게 했다고 이름이 같은지 모르는 MacOS X 파일시스템같은
상황이 없어집니다. 파이썬에서는 여러모로 내부 목적에 적합하다고 판단하여 NFC로 결정하였습니다.
사실 NFD와 NFC 사이에서는 간단하게 결정되었지만, NFKC와 NFC중에 무엇을 택할지는
좀 애매한 문제여서 토론이 있었는데, 결국은 손실 없이 최대한 줄여 쓰는 NFC를 채택하게 되었습니다.
(NFKC는 손실을 감수하고 줄여씁니다.)
그 외에도 역시 거의 유니코드 글자 속성 전 영역에 대해서 문제가 발생하는데, 이런 것이 있습니다.
Breaking: 각 글자가 앞 뒷 단어를 떼어주는 역할을 하는지 속성을 지정합니다. 예를 들어,
한글{ZWNBS}메롱 이라면 "한글{ZWNBS}메롱" 전체가 한꺼번에 변수 이름이 돼야 하지만,
한글{ZWBS}메롱 이렇게 썼다면 "한글" "메롱"이 따로 따로 변수 이름으로 인식돼야 합니다.
(ZWBS=Zero-Width Breaking Space, ZWNBS=Zero-Width Non-Breaking Space)
그런데, ZWBS같은 경우에는 눈에 안 보이기 때문에, 사람 눈으로 파이썬 소스를 완벽히 분석할
수 없다는 문제가 발생합니다. 그렇지만, 이런 건 변태들이나 하겠지;; 하고 어쩔 수 없는 문제가
아닐까 하는군요.
글자 속성: 아스키 문자영역에 대해서는 몇 글자 안 되다보니, 어떤 것이 부호이고, 어떤 것이
글자인가가 상당히 명확하지만, 유니코드까지 가게 되면 명확하게 숫자, 문자인 것이 있는 반면에
어떤 것은 숫자인것 같기도 하고 아닌 것 같기도 한 것들이 수도 없이 많습니다. (예를 들어,
홍콩지역 기수법 문자라던지, 네모 안에 숫자로 들어있는 것 같은 것들은 유니코드 데이터베이스에서는
여러가지 속성이 같이 기록되어 있지만, 프로그래밍 언어 측면에서는 숫자로 인정해야 할지 변수 이름 글자로
인정해야 할지 무지 애매하죠.. 10진법을 뛰어 넘는 숫자까지도 존재해서..) 그래서 각 글자 속성에
대해서 어떤 것을 변수 이름으로 인정하게 하고, 어떤 것을 허용하지 않을지 결정하는 것이 중요한데,
더욱 애매한 것은 유니코드 버전이 올라가면서 글자가 추가되거나 기존 글자의 속성이 바뀌는 경우도
있다는 것입니다. -ㅇ-;; (그래서 파이썬에서 지원하는 유니코드 버전이 바뀌면 소스 파싱 방법도 바뀌고..)
왼쪽으로 쓰는 문자체계: 아랍어나 히브리어 같은 경우에 오른쪽에서 왼쪽으로 쓰기 때문에,
유니코드 처리에서도 상당히 특별하게 처리해 줘야 합니다. 여기서 이제 파이썬 소스코드를 보는 쪽 뿐만
아니라 소스코드를 출력하는 부분이 있는 traceback이나 IDLE등 수많은 곳에서 오른쪽에서 왼쪽으로
쓰는 처리를 해 줘야하게 됩니다.
유니코드 쪽의 문제 뿐만 아니라, 파이썬에서 유니코드ID를 디폴트로 허용할 것이냐, 소스쪽에서
옵션으로 풀것이냐, 아니면 파이썬 명령행에서 풀게할 것이냐 등등 디폴트 설정에 관해서 의견이
많이 있었는데, 이건 아직 의견이 팽팽하게 맞서고 있어서 결정되지 않았습니다. 심지어 어떤 사람들은
위에서 언급된 것들 (NFC냐 NFKC냐, 문자 속성 선택 등..)을 런타임에 결정할 수 있게 하자는
사람도 있는데.. 역시 사람들 의견은 정말 다양하군요 -ㅇ-;
그 외에도 여러가지 기술적 문제들이 남아있지만, 결국 정책적으로는 귀도가 파이썬의 내부
파이썬 코딩 스타일 가이드인 PEP-8에서
절대 파이썬 자체 코드 안에서는 ASCII 이외의 문자를 쓰지 말도록 정하였고, 광범위한 개발자들이
참여하는 모든 오픈소스프로젝트에서도 이 규칙을 채택하도록 권고하는 것으로 결정했습니다.
이제 파이썬3000이 나오면 왠지 교육용으로 추천해도 마음에 찔리는 게 없을 것 같아서 무척 좋군요! :)
대충 보기엔 별 공통점이 없어 보이는 프로그램 이름들과 회사(기관)이름들이 있습니다. 이들은 무슨 공통점이 있을까요? -- 뻔한 퀴즈지만 파이썬을 주된 도구로 채용한 프로그램이나 기관들입니다. :) 이미 익숙하게 알려진 것들이 많지만 얼마 전에 우리에게 친근한 새로운 용례가 또 추가되었습니다. 바로, 다음 웹검색[1]에서 파이썬을 프론트엔드에 도입한 것입니다! (추측컨데 크롤러와 인덱스 빌더 등에서도 많이 사용했을 거라고 생각됩니다.)
이제 파이썬은 대안언어를 넘어서서 제 자리를 확실히 잡은 듯 합니다. 요즘 과학 논문에서 파이썬으로 된 도구를 보는 것은 아무렇지도 않은 일이 됐고, 이제 학교에서 어떤 과목 프로젝트를 하다가, 같은 조원이 파이썬이란 언어가 있는데 자기가 써보니 괜찮다더라 하면서 소개를 해 줄 정도로 잔뿌리를 널리 폈습니다.
그래서 2000년부터 최근까지의 파이썬 관련 행사들이 대부분 소개를 주목적으로 했다면, 이제는 파이썬을 활용하는 사람들이 새로운 만남을 통해 동기와 아이디어, 새로운 시각을 얻을 수 있는 모임이 필요할 때가 아닌가 생각됐습니다.
마침 서울에 가고 싶은데 핑계도 없고 해서 --; 뭔가 행사를 한 번 만들어 보고자 생각을 좀 해 봤는데, 그냥 옛날 스타일 컨퍼런스도 식상하고, 요새 많은 그냥 언컨퍼런스도 부담이 많고 해서 올해 초의 한국 루비 포럼 세미나의 형식을 약간 따 와서 이런 것을 생각해 봤어요.
먼저 간단한 파이썬 문제 -- 프로그래밍 학습에 쓰이는 장난감
문제 뿐만 아니라, 각 활용 분야별 특성을 잘 나타내는 아주 작은 장난감 문제들 -- 를 웹에서 모집합니다. 모집은 물론 공개된 방법으로 누구나 올릴 수 있고, 서로 평가해서 높은 순위에서 적당히 몇 개를 추립니다. 여기서 추려진 문제는 행사 시작 1주일 전 공시되어서 행사 참가자들은 자기가 참가할 세션의 문제를 혼자서 풀어봅니다.
그리고 행사 당일에는 OST 형식의 자유토론(과 미리 정해진 코너가 혼합되어)으로 해당 장난감 문제를 푸는 방법에 대해서 참가자들이 돌아가면서 설명해 보고, 거기서 파생되는 테크닉과 여러 습관, 기술, 관련 소식, 경험 등을 얘기합니다. 너무 주제가 산으로 가거나 제한 시간이 지나면 일단 중단하고, 누군가가 다음 세션으로 또 그것을 이어갈 세션을 만들기도 하고 여러 개로 나눠질 수도 있겠죠.
이런 방식의 세션을 제약 없이 연속적으로 3시간 정도 진행하고
잠시 쉬는 시간이나 적당한 공통 세션 후에 다시 또 3시간. -ㅇ-;
특히 게임, 과학계산, 시뮬레이션, 금융전산, 사회학정보처리 분야 같이 기존의
프로그래밍 언어 행사에서 포용하기 힘들었던 분야의 분들이 장난감 문제를 뿌리로 해서 얘기를 뻗어나갈 수도 있겠다는 점에서는 긍정적인 효과가 있지 않을까 생각됩니다.
보통 학교나 회사에서 알려주지도 않고 뭘 진행해 놓고서 나중에 왜 인트라넷에 공지 올렸는데 안 봤냐고 그러는 경우가 종종 있습니다. 옛날에 있던 학교에서는 그래도 과사에서 여러 방법으로 알려주려고 시도를 많이 했었는데, 새로 온 학교는 이거 거의 알아서 찾아봐야 먹고 사는 분위기네요. 으흐흐. 게다가 인트라넷은 Firefox로는 로그인도 안 돼서 FreeBSD에서는 도대체 볼 수가 없어서, 애로사항이 여간 아닙니다. 으흐~
그래서, 요새 절정의 인기를 구가하고 있는 mechanize로 게시판 긁어오는 스크립트를 만들어서 전에 식당 메뉴 만들듯 RSS로 만들어 보기로 마음 먹었습니다. 요새는 웬만하면 정보가 사람을 찾아와야지 사람이 정보를 찾으러 다니는 시대는 지났응께~
우선, mechanize는 아시다시피 쿠키와 참조URL 처리, 폼 처리를 자동으로 해 주기 때문에, 간단한 홈페이지를 따라가는 데는 더없이 편합니다. 그래서 웬만한 웹 스크래핑에는 항상 따르는 괴로운 순간 (스트레스가 슬슬 머리 위로 올라오면서, 계속 발생하는 예외상황과 이상한 HTML에 내가 이 일을 해서 뭐가 좋다고.. 하는 번뇌 등등..)이 거의 없이 한 페이지 보고 토닥토닥 해서 한 페이지 지나가고 리듬감을 잃지 않고 정보 수집이 끝났습니다. 역시 개발에는 리듬을 깨는 요소가 최대의 적입니다.
그리고, RSS는 지난번에는 손으로 짜서 print했더니 아침놀군이 HanRSS에서 이상하게 나온다고 하여서, 이번엔 제대로 된 RSS제너레이터를 사용했습니다. 훨씬 쉽고 좋네요~
그리하여, 만들어진 것이 이렇게(svn) 되었습니다. :) 이제 윈도우 들어가서 ActiveX와 씨름하지 않고도 학교 공지사항을 보고 장학금 신청을 할 수 있게 되었군요. -ㅇ-; (그러나 학점 미달로 인해 장학금 신청 자격이;;;)
오늘은 통계 숙제를 하다가, math.e math.log 이런 것 누르려다 보니, import math하기가 갑자기 무지 귀찮았습니다. 맥에서는
파이썬 대화모드는 거의 항상 WidgetTerm에 항상 띄워두고 쓰지만, math나 urllib같이 늘 쓰는 모듈을 쓸 때에도 import하고 쓰는게 그렇게 귀찮았구나~ 하고 옛날 생각도 나면서.. 흐흐
그래서 예전에 올라왔던 자동 들여오기 PEP가 생각나서 봤는데, 게으른 모듈(lazy module)을 일일이 다 만드는 방법으로 처리해서, 소스가 상당히 길고 설치하기가 귀찮더군요. 그래서, sys.excepthook을 써서 어떻게 NameError를 잘 지지고 볶으면 될 것 같아서. 한번 해 봤습니다~
# use as a PYTHONSTARTUP script for your interactive env.
import sys, re
def autoimp(tp, value, tb, orighook=sys.__excepthook__, re=re):
if tp is NameError:
name = re.findall("name '([^.']+)'", value[0])[0]
frame = tb.tb_frame
try:
mod = __import__(name)
except ImportError:
pass
else:
print "[[ Module '%s' is implicitly loaded. ]]" % name
frame.f_locals[name] = mod
exec frame.f_code in frame.f_globals, frame.f_locals
return
# bypass the exception to the original handler
orighook(tp, value, tb)
sys.excepthook = autoimp
del sys, autoimp, re
실행해 보면~
% PYTHONSTARTUP=autoimp.py python
Python 2.4.4 (#2, Apr 4 2007, 23:05:50)
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> math.log(math.pi)
[[ Module 'math' is implicitly loaded. ]]
1.1447298858494002
>>> math.sqrt(_)
1.0699205044532047
>>> len(urllib.urlopen('http://openlook.org').read())
[[ Module 'urllib' is implicitly loaded. ]]
42911
적당히 디스크 어딘가에 풀어두고, PYTHONSTARTUP 환경변수로 파일이름(전체경로)를 써 주시면 되겠습니다. 셸 프로파일에 적어주시면 편합니다~ ^^
주의사항: 여러 줄 블럭이거나 한 줄에라도 부작용(side effect)이 있는 코드이면 원래 의도와 다르게 동작할 수 있습니다.
A~Z까지 알파벳으로 이뤄진 5글자 단어를 모두 검색해서 뭔가를 한다거나, 아들 이름 지을 때 성을 제외한 2글자에서 가능한 모든 조합을 하고 싶은 것 같은 경우가 있습니다. 여러 다양한 상황에서 전혀 주먹구구식 알고리즘이 안 나오고 그냥 NP-complete 문제를 위한 정공법으로 전수조사를 해야할 때면 순열을 만드는 것이 가장 간단한 경우가 많겠죠. 순열 만드는 것이 간단하면서도 뭐가 좋을지 고민을 좀 하게 만드는데, 그래서 파이썬에서 순열을 만들 때 쓸만한 방법을 대충 생각나는 것을 모아 봤습니다. ^_^
우선, 일반적으로 나오는 C언어 입문서에서처럼 다 풀어쓰기를 하면 보통 이런 식으로 구현될 것입니다.
alpha = 'ACGU'
u = len(alpha)
depth = 3
# 위 3줄은 앞으로 공통으로 쓰일 것이므로 뒤에는 생략합니다.
# 1
seqs = []
for a in alpha:
for b in alpha:
for c in alpha:
seqs.append(a + b + c)
뭔가 한 눈에 확 들어오는 간단함은 있지만, 반복 수가 변하는 경우에는 루프가 늘어나고, 별로 코드도 중복이 가득해 보이는 것이 그다지 멋있지 않습니다. 그래도, 일단 좀 더 파이썬 코드처럼 보이게 하기 위해 줄여 보면,
# 2
seqs = [a+b+c for a in alpha for b in alpha for c in alpha]
이제 1줄로 줄기는 했지만, 내부적으로는 구조는 1번과 다를 것이 없습니다. 반복횟수가 바뀌면 여전히 루프가 늘어납니다.
그래서, 루프를 1개로 줄이고, 보통 많이 쓰이는 나누기 나머지 나누기 나머지 방법을 쓰면 이렇게 약간 일반화를 할 수도 있겠죠.
# 3
seqs = []
for i in range(u**3):
seqs.append(alpha[i // (u**2)] + alpha[i // u % u] + alpha[i % u])
루프는 1개로 줄었지만, 여전히 3개로 제한되어 있기는 마찬가지입니다. 이번에는 alpha에 매핑하는 부분도 일반화를~
# 4
seqs = [''.join(alpha[i // (u**d) % u] for d in range(depth))
for i in range(u**depth)]
자 이제 코드도 줄고 depth만 바꾸면 길이가 마음대로 바뀝니다~ 그렇지만, 약간 계산 오버헤드가 늘기는 했겠죠. -ㅇ-;
순열이 완전히 다 필요한 경우가 아니라, 일부가 필요한 경우이거나, 순열에서 쓰는 원소의 메모리 크기가 엄청 커서 복잡한 경우 등 여러 독특한 경우에는 순열에서 만들어지는 놈을 필요할 때 계산하는 것이 유용할 수도 있습니다.
# 5
class LazyPermu(list):
def __getitem__(self, idx):
i = list.__getitem__(self, idx)
return ''.join(alpha[i // (u**d) % u] for d in range(depth))
seqs = LazyPermu(xrange(u**3))
자, 이번엔 접근법을 약간 바꿔서 숫자를 안 쓰는 방법을 생각해 봅시다. 빈 것에서 시작해서, 모든 경우를 한 번씩 추가한 것을 원하는 횟수만큼 계속 더해주는 방식으로 하면 되겠죠.
# 6
seqs = ['']
for i in range(depth):
seqs = [seq+a for seq in seqs for a in alpha]
알고리즘의 계산 복잡도는 약간 안 좋아졌지만 -- O(MN)에서 O(MN+2)로.. -- 짧은 순열에 대해서는 그다지 차이는 안 날 것 같고, 코드도 그런대로 알아보기 쉬워졌습니다~ ^_^
이번엔 또 접근법을 좀 바꿔서, 행운을 믿는 사람이라면 순전히 랜덤 함수에 기대어 빨리 끝나기만 기다릴 수도 있겠습니다;;
# 7
from random import choice
seqs = set()
while len(seqs) != u**3:
seqs.add(''.join(choice(alpha) for i in range(depth)))
전체 순열이 필요할 때 이걸 실제로 쓰게 되지는 않겠지만, 순열이 굉장히 커서, 전체를 메모리에 담고 있을 수 없을 때, 순간 순간 생성하되 랜덤한 순서가 필요할 때는 이것도 쓸모가 있겠죠;;; (억지로 짜낸 용례 -ㅇ-)
정말 심심할 때는 추후 고객의 업그레이드 유도를 위한 "바쁘게 돌아가는 인터넷 속의 쉼터"(TM)로 이렇게 만들어 볼 수도 있겠습니다;;
# 8
import re
pat = re.compile('[%s]{%d}' % (alpha, depth))
seqs = set()
rnd = open('/dev/random')
while len(seqs) != u**3:
map(seqs.add, pat.findall(rnd.read(10240)))
아하하;;;
자.. 이제 파이썬에서 순열을 구하는 여러가지 방법을 알아 보았는데요, 어느 한 방법이 꼭 좋다기보다는, 상황마다 고려해야할 것이 많이 있겠죠. 예를 들면,
순열이 무지 길고 크고 루프가 오래 돌아간다 --> 순열을 생성하는 놈을 제너레이터로 만들어서 한꺼번에 메모리를 왕창 안 먹고 있게 한다.
분산처리를 해야한다 --> 단일 숫자 인덱스를 기반으로 한 순열이 아무래도 쪼개기가 좋겠죠.
항상 2개가 쌍일 뿐이다 --> 그냥 1번처럼 for루프 2개 돌려도~
순열에 랜덤하게 왔다갔다 접근할 필요는 있는데, 메모리는 적게 쓰고 싶다 --> 5번 같이 순간순간 짠~하고 만들어주는 녀석을 쓰세요~
KS X 1001 글자들 같이, 순열은 순열인데 종종 코드 곳곳이 비어있다! --> 파이썬의 리스트 컴프리헨션 뒤에 if 붙이는 문법은 정말 멋집니다~ -.-b
누구나 금방 알아볼 수 있는 코드로 만들고 싶다 --> 몇개 안 되면 좀 촌스러워도 1번처럼 짜거나, 순열 만드는 놈을 제너레이터로 빼서 이름을 잘 지으세요~
오늘은 자바로 된 간단한 프로그램 하나를 받아서 어떻게 컴파일할까 한참 고민을 했습니다. (자바 컴파일 하는 방법을 까먹어서;;) 소스를 보니 무지 간단한 것만 쓰고 별로 길지도 않아서, 얼마 전에 봤던 java2python으로 돌려 봐도 괜찮지 않을까하는 생각이 번뜩!
java2python은 java 소스의 기초적인 문법을 파이썬 문법으로 바꿔주는 것인데, API를 바꿔주지는 않는 간단한 정책을 취하는 놈입니다. 일단 까는데는 파이썬 2.5 이상이 필요하고, ANTLR 파서 라이브러리에 파이썬 지원을 추가해서 깔 줘야합니다. 파이썬 2.5 이상인 이유는 바로 그 A if B else C 문법을 썼기 때문이죠 --;
이렇게 자바의 메인 클래스 형태는 그대로 바로 클래스로 만들고 그걸 끝부분에서 호출해 주는 형태로 만들어줍니다. 다른 부분도 거의 건조체 번역을 보듯 완전 1:1로 번역되어 있는데, FileStream이나 IOException같은 것도 원래 자바 이름 그대로 되어 있습니다. 그래도, +=나 ++가 안에 들어간 부분이나, API가 안 바뀐 부분 몇 줄 고치니까 그런대로 잘 돌아가네요. :)
자바 -> 파이썬 포팅하기가 너무 귀찮은 분들은 우선 이걸로 번역해 놓고 손을 보는 것도 괜찮은 방법인 듯 합니다~
오늘 OSNews에 파이썬으로 된 리눅스 배포판인 Pardus에 대한 소개가 올라왔습니다. 여기저기 언급이나 도메인 이름을 봐서는, 터키 사람들이 주축이 된 것 같은데, 놀랍군요. 우리나라도 이런 걸 하나 만들어야하는데.. 흐흐
어떤 식으로 파이썬을 썼는지에 대한 소개도 나와 있습니다. 젠투가 파이썬을 사용자에게 노출하지 않고 그냥 툴로만 사용한 반면, Pardus는 scons처럼 빌드 스크립트 자체를 다 파이썬으로 작성하게 했군요. 심지어 네트워크 설정, 업그레이드 시나리오, 부팅 스크립트까지도 파이썬으로 되어있는 것이 아주 멋있습니다. :) 그래 이제 하드웨어가 웬만큼은 빠르군요 흐흐.
파이썬을 도입하면서 있었던 문제로는 tarfile이나 zipfile모듈과 호환되지 않는 놈들이 어쩌다 하나씩 있었는데, 금방 고치기는 했다는군요. 그리고, 압축파일을 푸는 동안에 메모리를 너무 많이 쓰는 것도 문제였는데, 한꺼번에 다 읽어서 풀지 않고, 적당히 버퍼를 둬서 풀도록 고쳤다고 합니다. 주 로켈이 무려 tr_TR.UTF-8인데, 파이썬에서는 절대로 ASCII외에는 디폴트로 안 만들어주겠다는 정책을 취하고 있어서 불편하다고는 하지만, 뭐 돌아가는 방법이 있으니까.. ^_^
최근 PyCon과 Google TechTalk에서 귀도가 Python 3000에 대해 발표하였습니다.
Python 3000에 대한 것을 귀도가 모두 모아서 직접 소개한 것은 처음이라는 점에서
많은 사람들이 관심있게 지켜보았는데요, 동영상이 무려 1시간 30분짜리나 됩니다만,
금방 맛보실 수 있게 간단하게 요약해 봅니다. 그런데, 귀도가 최근에 무척 늙은 것 같더군요.
몇년 전부터 팀도 겉으로 보기에 급속도로 늙고 있어서 안타까움을 느끼고 있는데, 귀도도 이제
나이를 어쩔 수는 없네요.. 으흐..
파이썬 3.0은 언제 나올 것인가?
스펙을 규정하는 PEP("펩"이라고 발음하더군요)은 2007년 4월까지, 첫 알파 버전은 2007년 6월,
2008년 6월에 최종 3.0 릴리스 예정이라고 합니다. 2.6은 2008년 4월을 예정하고 있고, 그 후로도
필요하면 2.7을 내놓을 예정입니다. 2.6은 주로 3.0으로 넘어가기 위한 여러가지 기능을 제공해 줄
예정이라고 합니다. 아마도 2와 3 모두를 지원하는 코드를
쉽게 작성할 수 있도록 몇가지 기능이 백포트될 것 같네요.
구식 클래스는 없다
2.1에서 들어왔던 new-style class가 이제 디폴트가 되어서, 구식 클래스가 사라지게 되었습니다.
둘의 차이를 직접적으로 항상 느끼는 분은 많지 않겠지만, 사용상 몇가지 연산자 정의나
상속 순위 같은 데서 차이가 납니다.
print가 이제 함수
종종 print 뒤에도 괄호를 쓰는 분들이 있긴 하지만, print는 그동안 statement였습니다. 이제부터
print도 abs나 sort같은 일반 내장 함수가 되었습니다. 그 말은, print뒤에 항상 괄호를 해야 한다는 것이고,
대략 보면 이렇습니다.
print x, y -> print(x, y)
print x, -> print(x, end=" ")
print >>f, x -> print(x, file=f)
물론 대부분의 경우에 이걸 자동으로 번역해 주는 스크립트를 샤샥 돌리면 해결되지만, 한 가지 경우에 호환이 안 된다고 합니다.
print "x\n", "y"
이런 경우 예전에는 y앞에 빈칸이 안 나왔지만, 앞으로는 y앞에도 빈칸이 들어간다는군요. 혹시 이것 원래부터 알고 계셨던 분도 있으시려나요? 파이썬에 이런 기능이 숨겨져 있는지는 저도 이번에 처음 알았습니다. -ㅇ-;
딕셔너리 뷰
예전의 토론에서는 딕셔너리의 items, keys, values가 모두 이터레이터를 리턴하도록 바뀌고, iter*는 없어진다고
얘기가 나왔었는데, 단순히 이터레이터를 리턴하는 것을 뛰어넘어서 새로운 타입을 리턴하도록 바뀐다고 합니다.
새로 리턴하는 것은 items와 keys의 경우 마치 set처럼 동작하는데, 원래처럼 내용을 보거나 훑을 수 있을
뿐만 아니라, 변경작업을 하면 원래의 딕셔너리에 반영도 할 수 있습니다. 반면에, values같은 경우에는
set처럼 변경작업을 하면 key로 뭘 넣을지가 모호하기 때문에, 그냥 읽기 전용이 된다고 합니다.
기본 비교 연산자의 동작 변화
이것도 많은 분들이 생각도 못했던 파이썬의 기능이 사라지는 것 같은데요, 파이썬에서는 그동안 객체의 기본
비교연산자가 모두 정의되어 있어서, 서로 다른 타입끼리도 말도 안 되는 비교가 가능했습니다. 예를 들어
dict와 list도 어느 놈이 크고 작은지 비교가 가능했고, 사용자가 정의한 클래스끼리도 비교가 됐죠.
(기준은 타입의 이름과 메모리 상의 주소랍니다. 으흐흐;;)
덕분에 서로 다른 타입이 잔뜩 들어있는 리스트도 정렬이 가능했었는데, 이제부터는 기본 비교연산자가
TypeError를 뱉게 했기 때문에, ["x", 1].sort() 같은 것은 불가능하게 되었습니다. 일일이 정해줘야 합니다.
문자열이 유니코드로
이제 기본적으로 ""로 쓰는 str타입이 유니코드 기반으로 바뀌고, 기존의 8비트 옥텟의 연속열이 str에서 bytes라는
타입으로 바뀝니다. 이미 많은 분들이 이걸 듣고 긴장하고 계셨겠지만, 그 영향은 굉장한데, 이제 ASCII 파일을
읽어서 바로 대문자로 바꾸거나 그런 것은 불가능합니다. bytes는 bytes일 뿐 문자열이 아니므로 글자 취급도
안 하고, x가 bytes타입이라면 x[0]같은 인덱스는 str과는 달리 아스키 숫자를 리턴합니다. 아직 자세한 것은
많이 결정되지 않아서, 혹시 관심이 있으신 분들은 참여하실 여지가 있을 것 같네요.
유니코드기반 문자열로 바뀌는 것은 최근 추세를 따라가는 것이기도 하지만, 파이썬을 처음 배울 때
유니코드가 뭐고 문자열이 뭐고 일일이 변환을 손으로 해 줘야 해서 굉장히 겁을 주는데, 이걸 해결할
뿐만 아니라, 유니코드를 전혀 모르는 서구권 개발자들도 얼떨결에 국제화된 프로그램을 만들게 하는
계기가 될 것 같습니다.
파일 입출력의 변화
문자열이 유니코드가 됐기 때문에, 파일을 바이너리로 열 때와, 텍스트로 열 때가 달라야하는 상황이 왔습니다.
따라서, 바이너리로 열면 read()하면 bytes가 나오는 대신 readline같은 것은 불가능해지고 (bytes는 줄같은 것은
신경 안 쓰므로) 텍스트로 열면 str이 나오는 대신 인코딩을 지정해서 변환 과정을 중간에 거치게 된다고 합니다.
지금의 codecs.open를 생각하시면 되겠습니다~
int/long 통합과 나누기 연산
int/long이 원래 2.2에서 통합되어서 내부적으로 자동 변환이 되고 있지만, 이제 겉에서는 전혀 눈치챌 수 없도록
완전히 int 타입 하나로 통합한다고 합니다. 이제 long이란 없고 그냥 큰 숫자는 내부적으로 BigNum류 연산을
쓰고, 작은 숫자는 CPU의 숫자 타입을 씁니다.
그리고, 2.2였던가요? 그때부터 __future__를 통해 지원되었던, "true division"이 기본이 됩니다. 1/2해도 이제
0이 아니라 0.5가 되고 2/2해도 1이 아니라 1.0이 됩니다.
예외처리의 변화
그동안 많은 파이썬 개발자들을 괴롭혀 왔던 except E, v: 이게 드디어 exception E as v로 바뀝니다.
예외를 여러 개 잡으려고 exception E1, E2 썼다가 E2가 무시되는 바람에 멀쩡히 돌던 프로그램이
퇴근만 하면 죽는 낭패를 봤던 경험이 있는
개발자들이라면 모두 쌍수를 들고 환영할 것 같네요. ^.^
또한, v가 그동안 try except 블럭 스코프가 아니라 그 외부의 스코프에 속해서 지워지지 않아서
try-except가 반복되다보면 메모리가 모자랐던 끔찍한 혼란이 드디어 해결됩니다. except 블럭도
스코프를 만들어서 except 블럭이 끝나면 v가 사라지게 되었습니다.
인자 시그너처 표시
C++이나 자바에서 넘어온 프로그래머들이 그렇게도 원하던 기능! 함수 인자에 타입 선언해 주기
비슷한 것이 추가됩니다. 정확히 말하자면 타입 선언이 아니라 그냥 인자 이름 옆에 """ 로 주석 쓰듯
뭔가 데이터를 넣어주는 것 뿐이고, 함수이름 밑의 속성으로 접근이 가능합니다. 이걸 활용해서
타입을 체크하거나 범위를 체크하는 데코레이터를 만들 수 있겠죠.
키워드만 받는 인자
그동안은 키워드 인자를 받도록 선언해 놓아도 왼쪽부터 순서대로 채워지기만 하면 키워드 인자까지
넘어와가지고 되는 경우가 있었는데, API 디자이너의 의도를 충분히 살려서 혼란을 없애고 싶은 경우를
위해, 키워드로만 받는다고 선언하는 문법이 생깁니다. 좀 문법이 희한한데,
def foo(a, b=1, *, c=42, d): …
로 쓰면, c와 d는 키워드 인자로만 받는다는군요;;
집합(set) 표기법
2.4에서 추가되어 굉장한 인기를 끌고 있는 set이 드디어 소스에서도 간단하게 쓸 수 있게
표기법이 추가됩니다. {1, 2, 3}으로 쓰면 set이 된다고 합니다. 즉, :가 없으면 set, :가 있으면
dict가 되는 것이죠. set comprehension도 물론 생깁니다. 흐흐
{f(x) for x in S if P(x)}
절대경로 임포트
파이썬 2.5에서 __future__로 숨겨져 있는 기능인데, 이제 패키지 경로의 혼란을 줄이기 위해서
패키지 내부에서 암묵적으로 상대적인 경로로 임포트가 가능하던 것이 금지됩니다. 이제 상대경로로
임포트를 하려면 . 이나 .으로 시작되는 다른 경로 이름을 써 줘야 하게 되었습니다.
문자열 포매팅
2.3인가에서 추가되었던 string.Template가 이제 표준 str타입의 % 연산자에서 지원되게 됩니다.
"See {0}, {1} and {foo}".format("A", "B", foo="C")
여기서 하나 궁금해 지는 것은, string formatting에서 항상
나오는 복수형 만들기 문제나 조사처리 같은 것을 써드파티에서
추가할일이 생길텐데요. 그런 경우를 위해서 사용자가 타입별로
제어할 수 있게 하거나 훅을 넣을 수 있게 여러 기능을 제공할 것 같습니다.
새로운 scope 선언자 nonlocal
파이썬 2.1에서 nested scope가 들어오면서 무척 편해진 것은 사실이지만 그동안 global과 local
밖에 없어서 상위 스코프가 global이 아닌 경우 상위 스코프의 뭔가를 건드리려면 list로 만들어서
넣는다던지 편법을 써야 했습니다. 이걸 위해서 스코프 블럭 앞에 nonlocal이라고 선언하면
이쪽에서 쓸 것은 아니니 nested된 윗쪽 스코프 것을 건드려라 하게 됩니다. 말로 들으면 복잡한데
실제로 사용한 예를 보면 나쁘지 않군요. :)
def outer():
x = 42
def inner():
nonlocal x # <---- new
print(x)
x += 1
return inner
switch/case ?
이 기능은 많은 사람들이 아주 옛날 1.4 시절부터 간절히 바라던 기능이고, 패치도 무척 많이 나왔는데,
결국 귀도가 PyCon에서 거수로 3.0에서도 안 넣겠다고 장난스럽게 결정했습니다. 흐흐. 아마도
귀도가 switch-case 싫어하는 것은 정말 오래전부터 일관적이었던 것이라서, 앞으로도 당분간은
들어갈 일은 없을 것 같네요. (파이썬에서 switch/case를 지원하는 것은 생각보다 많은 모호점을 만들어냅니다.
한 10분만 생각해 봐도 끔찍해서 그만 생각해야겠다고 덮어두게 되죠;)
그 외의 자잘한 변화
exec가 print와 마찬가지로 키워드에서 빠지고 내장함수가 됩니다.
range 내장함수가 xrange로 대체됩니다.
input 내장함수가 raw_input로 대체됩니다.
zip 내장함수가 이터레이터를 리턴합니다.
intern 내장함수가 sys 모듈로 이사갑니다.
__nonzero__ 오퍼레이터 이름이 __bool__이 됩니다.
파이썬 2.5에서 추가됐던 with가 3.0부터는 디폴트로 키워드가 되고, as도 마찬가지로 키워드가 됩니다.
``로 repr()할 수 있었던 것이 이제 불가능합니다. code golfer들에게는 슬픈 소식이네요.
<> 연산자가 없어집니다.
apply 내장함수가 없어집니다.
coerce 내장함수가 없어집니다.
dict.has_key 메쏘드가 없어집니다. 2.3부터 in 연산자로 대체되었죠.
그 외의 주요한 변화
지금 거의 단일 단계로 쫙 펼쳐져 있는 라이브러리들이 Java나 .NET처럼 체계화된 모양을
어느정도는 갖추게 될 예정인데, 많은 사람들이 지금 토론중입니다. 그리고, C API도 변화되게
될 것이지만, 가장 큰 문제로 지금 많은 함수들이 char*을 받고 있는데, 문자열이 유니코드로
바뀌게 되어 버렸으니, 이걸 어떻게 적용할지 고민이 되게 될 것 같네요. 원칙은 함수를 추가하거나
지우기는 하겠지만, 원래 있던 함수나 API에서 인자 개수만 바꾸거나 타입만 바꾸는 일은
없을 것이라고 합니다. 이렇게 되면 컴파일러 에러로 대부분 다 깔끔하게 잡아낼 수 있겠죠.
오늘 파이썬 3000을 위해 할 수 있는 일
웬만한 것은 자동으로 변환할 수 있게 될 것이니, 걱정할 필요는 없고, 지금부터 짜는 소스는
파이썬 3000에 대비하여 호환성 있는 코드를 짜도록 노력해야 합니다.
파이썬 2.6이 나오면 2.6을 사용합니다.
최대한 기존의 코드 전체를 커버하는 유닛 테스트를 작성합니다.
dict.keys()를 되도록 sorted(d.iterkeys())로 씁니다.
list타입이 넘어오는 것이 진짜로 필요한 경우에는 list(d.iterkeys())를 씁니다.
모든 exception을 Exception클래스에서 상속 받도록 합니다.
모든 클래스를 object 클래스에서 상속 받도록 합니다.
int끼리 나누는 경우에 // 연산자를 사용합니다.
기다릴 수 없어!
파이썬 3000 기다리기가 정말 괴로우시겠지만, 항간에 떠도는 "파이썬 3000도 펄6 꼴 날거야"
"파이썬팀이라고 별 수 있나 보나마나 계속 매번 6달씩 연기한다고 발표하다가 결국 5년 걸릴걸?"
이런 소문들은 거의 현실이 될 것 같지 않습니다. 귀도가 하겠다고 한 것은, 정말로 거의 금방
이룰 수 있는 것만 공약하고 있으며, 언제 끝날지 모르는 대공사는 최소한으로 줄여서 몇 개에
불과합니다. 정말 멋진 게 하나 나올 것 같지 않습니까? 매일 기다리기 지루하시면
달력에 2008년 6월까지 남은 날짜를 계산해서 X표시를 하면서 기다려 보세요. :)
지난 번
파이썬 GIL 깊숙히! (상)을 쓴 이후로 그 글을 읽으신 분들의 느낌을
IRC, 오프라인, 블로그 등을 통해 많이 전해 들었습니다.
별 다른 코멘트 없이 사실을 전달하는 정도로만 써서 그랬는지, CPython의 구현에 굉장히 심각한
문제가 내재되어 있는 것처럼 느껴지고, 이것 때문에 파이썬에 크게 실망하신 분들도 있는 것 같습니다.
그렇지만, 파이썬의 GIL은 "문제"라기보다는, "특성" 정도가 훨씬 적당하지 않을까 싶습니다.
파이썬과 같은 높은 수준의 객체 추상화를 사용하는 언어는 필연적으로 객체들의 작업들을 내부적으로
구현하기 위해서 여러가지 lock 방법이 필요합니다. 프로그래밍 언어 뿐만 아니라, 사실 한정된 자원을
공유하는 운영체제, 플랫폼 시스템, 데이터베이스 등등 대부분의 프로그램이 그렇겠죠.
그런데, GIL은 lock을 구현하는 방법 중의 하나일 뿐입니다. GIL에 반대되는 fine-grained lock은
lock을 관리하는 부가적인 자료구조가 필요하고, lock이 세분화 되어있기 때문에 그에 따라 한 번 lock
하면 될 것을 여러 번 lock해서 작업해야하는 경우가 많이 생깁니다. lock 여러개를 왔다갔다 하느라 문맥 전환 오버헤드나 캐시 손실도 발생할 수 있고요. 또한, fine-grained lock은
데드락같은 상황을 해결하기 위한 방법을 추가로 사용해야합니다. 만약 운영체제의 디스크자원,
Bus I/O자원, 그래픽자원 등과 같이 종류도 다양하고 수도 많은 경우라면 당연히 서로 병렬로 작업이
효율적으로 일어나게 하려면 fine-grained lock을 사용해야 합니다. 그렇지만, 파이썬에서 필요한
lock은 대부분 CPU가 주요 자원으로 참여하는 것으로, 사실상 이전의 PC들이 대부분 CPU가 1개
였다는 점에서, GIL을 사용하는 것은 (1) 구현이 쉽고 (2) 프로그램이 효율적이고 (3) 구현의
복잡도가 낮아서 유지보수가 쉬우며 버그도 적게 해 줍니다.
CPython을 구현한 그룹은 기업 규모의 다른 팀들에 비해 상당히 작은 규모이며, 특히 플랫폼에 최적화된 복잡한 JIT와 객체 시스템을 구현한 뛰어난 VM을 Sun이나
MS같이 직접 제작하여 유지보수할
수 있을만한 크기가 전혀 아닙니다. 따라서, 한정된 개발자들이 파이썬 고유의 역량을 그의 특징을
살리는 데 투자하기 위해서는 복잡한 VM을 구현하는 것보다는, 새로운 라이브러리와 언어적 측면들을
발전시키는 것이 더욱 중요했고 그렇게 계속 발전되어 왔습니다. 또한, 이렇게 만들어진 파이썬 언어는
결국 IronPython이나 PyPy같은 더 높은 이상을 추구하는 프로젝트가 나올 수 있게 된 기반이 되었겠죠.
그리고, GIL을 "문제"로 보기 힘든 또 하나의 이유는, 운영체제나 데이터베이스같은 시스템과는 달리
파이썬은 프로그래밍 환경이기 때문에, 사용자가 GIL이 있다고 해도 더 좋은 방법들을 개발하여 쓸 수
있다는 것입니다. 사실 쓰레드 프로그래밍은 프로그램 안에서 여러 문맥을 쓰기 위한 좋은 방법 중의
하나이긴 하지만, 대부분의 경우에 쓰레드를 사용하는 부분을 멀티 프로세스로 처리하는 것도 가능하고,
그게 오히려 더 효율적인 경우가 많이 있습니다. 예를 들어, 과학 계산을 위한 프로그램을 CPU가 20개라서
쓰레드 20개로 돌리게 만들었다면, 이 경우 입력값과 출력값을 관할하는 한 프로세스와 다른 20개 프로세스가
서로 통신하게 분리해서 짜는 것도 가능하고 (통신 방법은 os.system 외에도 무궁무진), 아예 범용으로
코드 객체를 던져주면 그걸 실행해주는 서버를 20개 띄워놓는 방법도 있겠죠. 이렇게 되면, 쓰레드 20개로
띄우던 시절과는 달리, 꼭 컴퓨터 1대에서 다 돌아갈 필요가 없어지고 10개, 10개 나누거나 2개씩 10대로
나누는 등의 설정도 생각해 볼 수 있게 됩니다.
어떤 분들에게는 GIL은 현재 파이썬 구현의 최대약점이라고 보이실 수도 있지만, GIL 때문에 도저히 같이
못 살겠다 해도 그것을 기회로 삼아, 쓰레드 말고 다른 방법으로 구현하는 방법을 배워보시는
계기로 만들어 보시면 좋겠습니다. =3=3=3
예고대로 (하)편에서는 GIL을 다루는 (피해가는?) 여러 방법에 대해서 소개해 드리겠습니다. ^_^
지난 8월의 대안언어축제에서는 Io 문법 발견하기를 했었는데요, 얼마 전의 오픈소스뛰어들기에서는 똑같은 포맷으로 Python 문법 발견하기를 진행해 보았습니다.
대부분의 참가자분들이 생소할 Io와 어느 정도는 익숙한 Python이 어떤 차이가 있을지 무척 궁금해서 참지 못하고 해버렸는데, 많은 분들이 참가해 주셔서 즐거운 경험이었습니다. ^^/
이번에는 똑같은 방법으로 2번 시행했고, 같은 자료로 똑같이 진행하려고 했음에도 불구하고, 첫번째와 두번째가 거의 중복된 주제가 없을만큼 완전히 다른 내용이 다뤄졌습니다. (진행한 사람이 이런 무책임한 -_-;) 사실 세션 내부에서는 대부분 참가자분들이 발견하신 것들과 질문을 위주로 진행했기 때문에, 참가자가 기존에 알고 있는 언어와 어떤 관점을 갖고 있느냐에 따라서 내용이 거의 눈감고 골프공 때리는 수준으로 결과가 달라지게 되는 것 같습니다.
첫 세션은 7분이 2,2,3명으로 조를 짜서 진행했는데, 10분 정도 지난 후부터 본격적으로 분위기가 달아올랐습니다. 첫 세션에 참가하신 분들은 C를 하시던 분들이 많았는지, 아무래도 제어구조나 자료형이 집중적으로 논의됐었습니다. 반면에 두 번째 세션에서는 자바를 하시던 분들이 많이 참여하셨는지, 객체적 성질을 자료에 거의 안 넣었음에도 불구하고 거기서 객체의 메쏘드 같은 것이 논의가 됐습니다. 두 번째 세션은 모두 12분이었고, 자리가 여의치가 않아서 4,4,4명으로 했던 것도 약간 변수로 작용한 것 같습니다.
지금까지 이런 형식으로 3번 진행해 오면서, 대부분 분들이 긍정적인 반응을 보여주시고 곧 익숙해서 능동적으로 참여하시는 것을 보고 앞으로 다른 곳에도 도입을 해 보면 재미있겠습니다. 다만, 부족한 점은 아무래도 실제로 코딩을 해보지 않고 차곡차곡 바닥부터 쌓아올리는 방식이 아니기 때문에, 약간은 사상누각이 되지 않나 우려가 있긴 합니다. 그래서, 적당히 보충하기 위해서는 1시간의 "발견"이후에 로제타카드 등을 이용해서 간단한 문제를 직접 페어로 해결하는 것이 바로 따라와줄 필요가 있을 것 같습니다.
그 외에도 몇 가지 아이디어를 생각해 보면, 각 페어들이 작업하는 것을 모두 스크린캐스트로 녹화한 다음, 화면에 동시에 2개 또는 4개를 배치한 다음에, 약간 빠른 속도로 플레이하면서 각 팀들의 의견이나 토론이 있으면 서로의 의견 차이와 잘 모르는 것을 안 수줍게 해결할 수 있는 자리가 되지 않을까 싶네요. 아무래도 생방송보다는 녹화방송이 편안하니까 ^.^;
기계공학의 최적화설계이론을 보면, 설계상의 몇가지 선택지가 있을 때 각각의 최적조건을 계산해서 유전자알고리즘을 사용하거나 동적계획법을 사용하여 여럿 중에서 계속 선택해 나갑니다. 튜토리얼에서 실습해 보는 간단한 프로그램에서도 이런 것들을 적용해서, 어떤 루프를 쓸 것인가, 어떤 자료형을 쓸 것인가 뭘 먼저할 것인가 이런 의사 선택을 모두 나열한 다음 (물론 작은 프로그램이니까 가능) 다른 페어들이 모두 각각을 경험해 보고 그 언어의 특성에서 어느 것이 더 좋았는지 얘기해 보는 것도 좋을 것 같구요~
대표적인 파이썬 구현인 CPython에서 거의 십년여 지속적으로 문제로 두루 지적 받아 왔지만 여전히 그대로 있는 것으로 바로 GIL (Global Interpreter Lock)이 있습니다. 점점 CPU 여러 개를 동시에 쓰는 시스템들이 많아지면서 특히 요즘 자주 언급되고 있는데, GIL은 짧게 말해 동시에 CPU를 1개 밖에 못 쓴다는 그 문제의 근원입니다.
역사적 배경과 존재의 이유
GIL은 처음 파이썬에 쓰레드 구현이 들어갈 때 같이 생긴 이후로, 지금까지 계속 내려오고 있습니다. 파이썬 구현은 상당 부분이 라이브러리 전역 변수에 의존하고 있고, 여기 저기 객체 구조에 따라서 참조를 따라서 마구 접근을 하기 때문에, 동시에 쓰레드가 여러 개 돌아갈 때 심각한 문제가 발생할 수 있습니다. 따라서, 파이썬은 초창기부터 파이썬 라이브러리 코드가 돌아가는 중에는 전역적인 락(GIL)을 걸어서 동시에는 절대로 같이 못 돌아가도록 해서 해결하였습니다.
물론 이 문제를 해결하기 위해
1996년과 2000년에 Greg Stein이 GIL을 완전히 없애고 섬세한 락(fine-grained lock)을 구현하였지만, 그 결과 SMP에서는 1.6배 속도가 빨라졌지만, 대부분의 사용자가 쓰는 UP에서는 엄청나게 느려져서 실제적으로 대부분 사용자들은 불평을 할 수 밖에 없었고, 그로 인해서 모듈을 만들기가 쉽지 않은 문제들과 복잡성이 증가해서, 다른 개발자들이 선뜻 유지보수 가능한 코드 개발에 나서지 않아서 그냥 GIL이 지금까지 남아있게 되었습니다.
GIL은 대략 어떤가?
위 그림에서는 메인 쓰레드와 거기서 띄운 쓰레드 3개가 같이 돌아가는 모습을 그려 놓았습니다. (못 생겨도 이해 바랍니다. ^^;) 파란색 상자가 돌아가는 상태에 있는 것을 표시한 것인데, 대충 눈에 보이듯이 동시에는 파이썬 쓰레드는 1개만 돌 수 있습니다. 여기서 파이썬 쓰레드라 함은, 파이썬 인터프리터가 호출하는 모든 코드를 뜻합니다. 즉, C코드와 파이썬 코드의 구분 없이 일단은 모두 파이썬 쓰레드처럼 동시에 1개만 돌아가게 GIL의 영향을 받습니다. 여기에 예외도 있는데 이것은 후에 설명하겠습니다.
쓰레드 실행이 바뀌는 시점은 언제일까?
파이썬은 아시다시피 내부적으로 바이트코드로 번역된 다음에 실행됩니다. 예를 들어 보면 다음과 같이 바이트 코드를 볼 수 있습니다.
평소에는 GIL을 꽉 쥐고 있다가, 각 줄을 파이썬 인터프리터에서 처리하면서 내부적으로 카운터를 1씩 증가시킵니다. 그러다가 100이 되면 GIL을 풀었다가 다시 쥐게 되는데, 풀었다 쥐는 사이 공간에서 문맥 전환(context change)가 일어납니다. 즉, 파이썬 인터프리터가 쓰레드가 1개만 뜨는 것이 아니라, 인터프리터도 쓰레드마다 도는데, 서로 GIL 때문에 동작은 1개씩만 하는 상황이죠. 그래서 그림을 보시면 자발적이 아니라 틱이 100이 돼서 전환되는 쓰레드들은 너비가 100의 배수로 되어 있습니다. 100이 어느 정도 범위인가 하면, 보통 쓰는 정도의 파이썬 코드 20~30줄 내외가 바이트코드 100줄 정도 되기 때문에, 그렇게 크지도 않고 작지도 않은 단위라고 볼 수 있겠습니다.
특별한 사건이란?
위의 그림 ①번에서 보듯이, 심지어 새로운 쓰레드를 시작할 때에도 즉각적으로 새 쓰레드가 실행되지는 않습니다. 기다리고 있다가, 원래 돌던 쓰레드의 카운터가 100이 돼야 돌아가게 됩니다. 그런데, 100개 단위로 일어나는 것이 아니라 "특별한 사건"이 있을 때는, 갑자기 100으로 퍽~ 뛰어서 문맥 전환이 일어납니다. 그림의 ②이나 ③은 틱에 의해서 전환된 것이지만, ④번 같이 블러킹 시스템콜이 일어나게 되면 select(2)하는 동안에 락을 걸고 있으면 다 멈추니까, 다른 쓰레드로 넘겨줍니다.
쓰레드가 어떤 순서로 실행되나?
위 그림의 ⑥번도 마찬가지로 시그널이 발생하면 일단 시그널을 큐에 쌓아둔 다음에 틱을 100으로 증가시켜서 즉각적으로 다른 곳으로 넘겨버립니다. (그래서 이렇게 시그널 핸들러가 직접 호출되지 않는 경우가 있기 때문에,
시그널 핸들러가 희한하게 꼬인 상황에서 엉뚱한 예외가 발생한다거나, 시그널 때문에 예외가 씹힌다거나, 순서가 뒤죽박죽이 되는 일이 일어납니다.)
그런데, 이게 쓰레드 구현마다 다르고 쓰레드의 종류마다 달라서, 일정한 동작이 있지 않습니다. 일반적으로 시스템 스코프 쓰레드들은 lock/unlock을 확인하는데 커널을 거쳐야하기 때문에, 굉장히 자주 바뀌고 순서가 아주 제멋대로인 반면에,
프로세스 스코프 쓰레드들은 lock/unlock을 프로세스 내부에서 처리해버리기 때문에, 좀처럼 잘 바뀌지 않고, 순서도 거의 일정합니다. 심지어 쓰레드 50개를 만들 동안에 50개 모두 전혀 실행 안 되고 버티는 경우까지도 종종 있을 정도입니다.
따라서, 쓰레드의 실행 순서나 실행의 정도에 의존하는 프로그래밍은 쓰레드
라이브러리가 바뀌면 안 돌아갈 수도 있기 때문에, 좀 생각해 볼 필요가 있습니다.
쓰레드가 1개만 돌면 난감하지 않은가?
CPU가 여러 개 있을 경우나 블러킹 시스템콜이 중간에 끼이는 경우 같이, 여러 개의 쓰레드가 꼭 동시에 돌아야할 때가 있습니다. 특히 GUI 네트워크 프로그램들 같은 경우에 반응성과 직결되는 문제인데요, 이 경우를 위해 명시적으로 일부분에서 락을 풀어주는 방법을 제공합니다.
위 그림의 ⑫와 ⑭사이가 그런 경우입니다. ⑫에서 Py_BEGIN_ALLOW_THREADS를 해 주면, 그때부터 그 쓰레드는 GIL과 상관 없이 다른 파이썬 쓰레드와 동시에 돌 수 있게 됩니다. 물론, 이 때에는 파이썬 함수를 호출하거나 파이썬 객체를 건드리는 등 파이썬과 관련된 것은 어떤 것도 해서는 안 됩니다. 이런 종류의 작업이 끝나면 ⑭번에서 Py_END_ALLOW_THREADS를 호출해 줘서 이제 그 쓰레드도 GIL의 영향 하에 들어가서, 문맥 전환을 기다리게 됩니다. 물론 즉시 바로 받는 것은 아니고 돌아가던게 100이 되길 기다리는 거죠뭐~ -O-
GIL을 왜 쓸까?
위에서 GIL을 대충 살펴봤는데요, 보시다시피 쿼드코어 CPU가 난무하는 이 시대에 좀 껄쩍지근~하게 들리는 것이 사실입니다. 그럼에도 불구하고 파이썬에서 GIL을 계속 쓰고 있는 것은, GIL이 UP에서 상당히 효율적이기 때문입니다. 파이썬 같이 객체가 많고 객체간 접근이 두리뭉실해서 효율적인 락을 구현하기 힘든 경우에는 필요 없는 락에
의해서 낭비되는 자원이 상당합니다. FreeBSD 4.x까지도 그랬듯이, 전체에 락을 거는 것은 상당히 코드의 복잡성을 줄여주고 UP에서 락에 자원을 낭비하지 않고 높은 효율성을 유지할 수 있게 됩니다.
그렇지만, 역시나 게임기에도 쿼드코어가 들어가는 세상이 되면서, MP지원의 중요성 은 점점 커져가고 있고, 파이썬도 나름대로 그에 대한 대처를 하려고 여러가지 이야기가 나오고 있습니다. 그에 대한 이야기는 다음 시간에~~
◈ 좀 더 자세한 것을 알고 싶으신 분들은 파이썬 소스 중 Python/ceval.c에서부터 보기 시작하시면 됩니다.
◈ 그림에 오류가 하나 있는데, 쓰레드 #1에서 ④~⑤사이에 비어있는 부분은 갈색 블럭이 되어야 합니다.
요즘 파이썬 웹계에서는 지난 주에 발표된 《The Django Book》이 굉장한 관심을 불러모으고 있습니다. 내년에 정식으로 출판될 책인데, 미리 독자들의 리뷰와 의견들을 모으기 위해서 인터넷에 본문을 공개한 것입니다.
종이로 된 책이 나오는 것 자체가 시장에서의 위치를 얘기해 주는 대략적인 지표를 넘어선 것이라고 볼 수 있어서 상당히 반가운 일이기는 하지만(최근에는 파이썬 수험서도 나왔죠! ^.^), 이 책에서는 공개한 방식이 무척 주목할 만 합니다.
우선, 전문을 한꺼번에 공개한 것이 아니라, 책의 일부씩 순차적으로 공개했다는 점이 중요한 듯 합니다. 전문을 공개했다면 이미 책이 완성돼서 출간되기 직전에 그냥 한번 입에 오르기 위한 것이 아닐까 하는 느낌도 들고, 사람들의 관심이 분산되었을텐데, 조금씩 조금씩 차차 공개함으로써, 사람들의 관심을 집중시킬 수 있으며 상호작용을 촉발시키는 중요한 계기가 된 듯 합니다.
또한, 웹 프레임워크답게 아주 편리한 웹 인터페이스를 제공해 주었는데요, 그동안 파이썬쪽에서 널리 쓰이던 Silva는 괜찮은 듯 하면서도 은근히 손이 점점 안 가게 되는 답답한 면이 많이 있었습니다. Django Book에서는 최근 유행하는 웹 기술들을 적용한 덕에, 점점 코멘트를 달고 싶어지는 UI를 잘 만들어낸 것이 아주 멋있습니다.
코멘트 시스템에 대한 설명을 보면, 개략적인 설명도 있는데 Yahoo! YUI를 썼다고 하는군요. 나중에 혹시 이게 범용으로 공개된다면, 책을 번역하거나 공개 리뷰를 하는 목적으로 매우 편리할 것 같습니다. +_+
오랫동안 제 마음 속 영웅 중의 하나인 제인 구달(Jane Goodall)박사가 학교에서 강연을 해서 듣고 왔습니다. 생물학과 교수님들이 사람이 너무 적을까봐 걱정하면서 꼭 가보라고 얘기를 했는데, 막상 가보니까 빈 자리가 없을 정도로 꽉꽉 들어차서 간신히 자리를 하나 찾아서 앉았습니다.
사회자가 소개를 하고 앞으로 딱 나오는데, 옷이 탐험복 비슷한 것을 입으신게 아 막 눈물이 쏟아지려하는 감동이.. 울컥~ 우흐흐. 처음에 인사를 하시는데, 침팬지 언어로 "Hi~"를 하는데, 진짜로 실감나게 동물의 왕국에서 봤던 침팬지 인사를 구사하시더군요. 저 정도면 진짜 침팬지랑 말이 통하지 않을까 생각..
오늘 강연 내용은 뭐 대체로 그동안 책에 있던 내용이 요약되어 새로운 것은 없었지만, 그래도 그 연세에도 일년 중 300일 이상을 환경과 미래를 지키기 위해 이런 저런 강연과 만남을 갖고 계신 것을 보면 정말 대단합니다. 저도 30살되기 전에 칼슘을 많이 먹고 운동을 꾸준히 해야겠어요;;
그리고, 책에서 꾸준히 나왔던 종교적인 신념에 대해서 어떤 학생이 질문을 했는데, 이제 더 이상 공적인 자리에서 기독교인이라는 것을 밝히고 있지 않고 진화를 지지하지만, 신의 존재에 대해서는 믿고 있다고 합니다. 그동안의 책과 어조가 약간 바뀌신 것이 흥미롭네요. +_+
우흐흣. 싸인 받았습니다. 자랑 -.-vv (사람이 너무 많아서 이름은 안 써주시더군요; 아쉽;)
nohmad님께서 개멍님의 글을 알려주셔서, 일단 직접적인 관련이 있는 당사자로 해명을 해 봅니다. ^^
CP949에서 '\\'는 u'₩'가 되어야 하는가?
우선 개멍님의 글 안에서 말씀하셨듯이 euc-kr이나 cp949에서 '\\' (즉 굴림체에서는 원화기호로 보이는 그것)가 유니코드로 u'₩'로 하는 것은 좀 곤란하지 않을까 합니다. 현재 CP949는 표준 문서가 따로 있다기 보다는 △ Microsoft 구현의 실제 동작 △ Microsoft가 Unicode Consortium에 제출한 코드 매핑 두 가지가 권위가 있는 근거로 볼 수 있습니다. 둘 다 '\\'에 대해서 U+5C (REVERSE SOLIDUS)로 매핑하고 있기 때문에, CP949측에서는 u'\x5c'로 하는 것이 적당하다고 생각됩니다.
EUC-KR에서 '\\'는 u'₩'가 되어야 하는가?
또한, EUC-KR에 대해서도 그런 매핑이 근거를 얻으려면 EUC-KR이 G0 영역(0x20-0x7f)에 KS Roman (KS X 1003)을 할당했다면 됩니다. 그렇지만, 현재 EUC-KR에 대해 권위가 있다고 판단되는 ISO측의 등록에서 G0 영역에 KS Roman이 아닌 US-ASCII를 할당하고 있기 때문에 당연히 0x5c에 대해서 U+5C를 매핑하는 것이 표준에 맞는 동작이라고 볼 수 있겠습니다. 즉, 위 두가지 상황에 대해 키보드에서 누르는 것과 화면에서 원화 기호로 보이는 것, 즉 입력기와 굴림체 글꼴의 버그라고 볼 수 있을 뿐, 인코딩 변환에 관련해서는 문제가 없습니다. 그렇지만 물론 키보드에서 원화 기호가 써 있는 키를 누른다고 해서 진짜로 ₩(WON SIGN)로 나와버리면 곤란하겠죠. 지금까지 전 국민이 U+5C를 써 왔으니..;
후에 추가: EUC-KR에 대한 표준은 찾아보니까 ISO보다는 KS X 2901이 더 권위가 있겠네요. :) 그 내용에 대해서는 신정식님의 메일을 참고하시면 명쾌하게 될 듯 합니다.
CJKCodecs에서 JIS 인코딩들의 같은 문제에 대해
반면 JIS 인코딩들 (SHIFT_JIS, EUC-JP)은 G0에 US-ASCII가 아니라
JIS Roman (JIS X 0201)을 할당하고 있기때문에 엔화 기호와
윗줄(OVERLINE)이 대신 변환되는 것이 옳습니다.
그렇지만, 위 글의 코멘트에서 토끼군이 답변하였듯이, 파이썬의 CJKCodecs의 2003년 말 버전에서부터 일본인 사용자들의 끈질긴 요청에 따라 기본 코덱들을 한국처럼 G0에 US-ASCII를 할당하도록
바꾸고, 대신 -strict라고 꼬리를 붙인 표준 준수 코덱들을 넣어
놓았었습니다.
그렇지만, 이것을 구현한 방식이 #ifdef를 이용해서 프리프로세싱을 2번 다르게 해서 표준/비표준 코덱을 구현한 것이다보니 파이썬에 CJKCodecs가 들어가면서 프리프로세싱을 임의로 제어하기가 힘들어져서 결국에는 -strict 코덱들이 모두 제거된 채로 들어갔고, 그로 인해서 표준을 준수하는 코덱이 빠지고, 실질적으로 일본인들이 사용하는 인코딩만 남은 것이 현재 상황입니다.
후에 추가: 일본 인코딩의 경우에도 photon님의 말씀과 다른 자료를 종합해보니, Shift_JIS나 EUC-JP모두 US-ASCII와 JIS X 0201을 어느 쪽을 써도 좋도록 하고 있다고 합니다. 따라서, 위에서 말한 엄격한 표준 준수라는 말은 모두 잘못된 표현이기에 바로잡습니다. ^^;
일본 인코딩 표준의 심각한 문제
사실 -strict 인코딩을 일본인들이 그렇게 싫어했던 이유는 한국 사람들 같이 그냥 단순히 보이는 것이 다르다 정도가 아니라, 아예 "코딩이 불가능"한 상황이었기 때문입니다. JIS Roman에서 교체하고 있는 글자가 2개가 있는데 엔화기호<->REVERSE SOLIDUS와 틸드<->OVERLINE 입니다. 그런데, REVERSE SOLIDUS같은 경우에는 굳이 쓰려면 JIS X 0208에 정의된 것을 쓰면 충분히 roundtrip도 보장되고 억지로 어찌어찌 되기는 하는데, 틸드의 경우가 심각합니다. 즉, JIS X 0208에 틸드가 없기 때문에, 결국 표준에 맞게 구현을 하다보면 SHIFT_JIS에서는 틸드를 아예 못 쓰게 되는 것입니다. 그래서 bitwise not같은 연산자로써나 "hi~~ o/~" 같은 경우에서나, 여러모로 아예 코딩이 불가능한 상황이 오게 된 것입니다. (파이썬은 2.4부터 "항상" UTF-8로 변환한 뒤에 토크나이징/컴파일을 하기 때문에 유니코드에서 뭘로 매핑되느냐가 굉장히 중요합니다.)
그래도 표준 지원..
사실 한동안 까먹고 있어서 진행이 안 되고 있었는데, 파이썬에 있는 CJKCodecs는 표준 지원을 위해서 다음 몇가지를 진행할 계획이 있습니다.
지난 대안언어축제에서 아마도 가장 긴 여운을 남겼던 것은 아무래도 마지막 자기 포부를 말하고 주변에서 환호성으로 축하해 주는 것이었습니다. 그게 원래 할 계획이 있었던 것이 아니라, 그 전날 다음 날 회고를 안 지겹고 인상에 남고 흥미롭고 지쳤을 때도 다 같이 좋은 분위기에서 참여할 수 있는 걸 찾기 위해 열심히 찾아낸 끝에 나온 아이디어였습니다. 그게 갑자기 뚝 떨어진 게 아니라, 뭘 할지 무척 고심을 하다가, 여유있게 어슬렁거리던 창준형이 갑자기 "비장의 무기를 준비했지!" 하고 자신있게 스으윽 꺼낸 것이 바로 Creative Whack Pack 이었습니다. 카드를 몇장 들고 보고 있으려니 갑자기 승범이가 "이게 좋을 것 같아요!" 그러더니 막 아이디어를 쏟아내는데... 흐흐 무척 탐나서, 돌아와서 바로 아마존에 주문해서 구입~ 마침 결제하려고 보니 아마존에서 할인 기간이라고 수퍼 세이버 시핑을 하는데 뭘 더 사면 싸다고 추천을 해주길래 Innovative Whack Pack도 샀지요. 순간 아마존의 상술에 속아서 -ㅅ-;
음 하여간, 요새는 FreeBSD의 파이썬 포트 때문에 무척 고생을 하고 있었습니다. 거의 1주일 넘게 거의 모든 여유시간을 포트 고치는데 쓰고 있는데도 아직도 고칠 게 200개 넘게 남았군요. =_=;;; 이번에 어찌하다가 6.2을 위한 포트 프리즈 직전에 파이썬을 2.5로 업데이트하게 되었는데, 그게 알고보니 대략 4가지 정도 되는 다양한 문제를 만들게 돼서, 파이썬을 쓰는 다른 포트들이 거의 500개 남짓 깨져버린 것이었습니다. 당연히 수많은 사람들이 메일링 리스트에서 난리가 나고, 포트매니저들도 말하고 그러지 그랬냐고 핀잔도 주고.. 아하하; 파이썬 2.2, 2.3, 2.4도 늘 프리즈 직전에 임포트 했었는데.. 관성이 문제를 일으키는군요 --;
점점 문제가 마치 괴혼에서 쓰레기 굴리듯이 불어나서, 2.4로 돌리느냐 문제를 계속 고치느냐 고민을 하고 있던 중에, Innovative Whack Pack을 한번 써 볼까 하고 손에 들었습니다. 사실 카드를 사긴 했지만, 학교 수업들을 다 순수과학 2학년 전공 과목을 듣다보니 쓸 일이 전혀 없더군요. 그래서 일단 마구 섞고, 3장을 뽑았습니다. 나온 것이 위의 3장~ insight 면에는 그림과 Heraclitus의 짧은 경구들이 있습니다. 그리고, strategy 면엔 밑의 문장이..
짧게 요약해 보면,
Donkeys prefer garbage to gold: 지금 열심히 하는 게 나중에도 중요한 일일까? 어떤 상황이 되면 그 가치가 변할까? 지금 생각하고 있는게 나중에는 쓸 모가 없어지지 않을까?
When there is no sun, we can see the evening stars: 문제에서 떨어져 봐라. 지금 해결하려는 문제에서 떨어져서 잠시 쉬면서 생각해 보았는가?
Sea water is both pure and polluted: for fish it's drinkable and life-giving; for humans undrinkable and destructive: 문맥을 바꿔보아라. 어떤 다른 문맥에서 니 생각을 다르게 생각해 봤니? 의미가 어떻게 변하니?
그래.. 가만 생각해 보니, 지금 포트를 열심히 욕먹어가면서 고쳐봐야 뭐 나중에는 별로 티도 안 날 것이고, 지금 남들이 고이 보지 않아서 조바심내가면서 하고 있는 포트 작업들도, 프리즈 기간이 아니라 그냥 평상 시 같았으면 잘한다고 고맙다고 그럴 작업이었던 것입니다. 으흐흐. 그래 파이썬 2.5를 넣어야 된다는 것을 먼저 불변의 목적으로 딱 박아두고 모든 것을 생각하고 있었는데, 그냥 빼버려도 별 상관 없을 것 같다고 생각하니 홀가분하고 좋습니다. ^_^* 이제는 프리즈 기간 직전에 이런 짓 안 해야겠습니다;;;
평소에 포팅을 하다 보면, 문제를 해결하는 방법이 무척 많은데, 뭘 선택해야할 지 고민할 때가 많습니다. 그래서, 포팅할 때 고려해야 할 때 선택이나 아이디어에 도움이 될 만한 것들을 모아서 portlint 같은 데서 엉뚱하게 한 개 씩 출력해줘도 좋지 않을까 생각을 해 봤습니다; 그런데 아무래도 카드로 만들어야 뽀대가.. 흐흐;
음.. 저는 할 줄 아는 게 없어서 그냥 구경만.. =3=3 날짜는 9월 23일 (토) 오후 중에 4~5시간 정도 이뤄질 예정입니다. 형식은 일반적인 튜토리얼 형식은 아니고, 대안언어축제에 참가하신 분들이면 쉽게 적응하실 수 있는 굉장히 능동적인 참여가 필요한 방식으로 진행될 것입니다.
구체적인 것들이 좀 더 결정되면 다시 알려드리고 광고를 하도록 하겠습니다. ^^ 지금으로써는 아마도 파이썬마을과 한국루비사용자포럼에서 각각 15명, 스퀵사용자모임에서 10명 정도씩을 따로 모집하는 형식으로 할 것 같습니다.
이런 것이 궁금하다, 이렇게 하면 좋겠다 등등 의견 있으신 분들은 답글 올려주시고용 +_+ 혹시 행사 당일 진행에 도움 주실 분들도 알려주시면 고맙겠습니다~ ^^
오랜만에 CJKCodecs의 버그가 발견되어서 수정하였습니다. Oren Tirosh씨가 전체 코덱에 대해서 roundtrip 테스트를 해서 결과를 보내 줬는데, 그 중의 일부가 버그로 밝혀져서 -O-;;
이제 berlios에 있는 공간은 배포용으로만 사용하고 있기 때문에, 그쪽에 커밋은 따로 하지 않았고, 파이썬 trunk로만 커밋했습니다. 2.5는 지금 브랜치가 갈라져 있어서 넣지 못했는데, 아무래도 지금 릴리스 직전이다보니 넣을 수 있는 가능성은 별로 높지 않고, 2.5.1에나 들어갈 수 있을 것 같네요.
수정된 버그의 목록은
gbk 인코딩에서 gb2312에서 U+30FB KATAKANA MIDDLE DOT이 먼저 매핑되는 바람에 에러가 나야하는 게 안 나던 버그가 수정.
gb18030 인코딩에서 마찬가지로 U+30FB가 gb2312 매핑에 가리는 바람에 유니코드 매핑이 아니라 다른 곳에 들어갔던 버그가 수정
iso2022-jp-2 에서 KS X 1001과 GB2312를 표준에서는 G0에 인코딩 해야 한다고 되어있는데, G1에 인코딩하고 있었던 버그를 수정
iso2022-jp-3과 iso2022-jp-2004에서 JIS X 0213:2 영역을 인코딩하지 못하던 버그를 수정.
[1] from twisted.internet.iocpreactor import proactor
[2] from iocpreactor import proactor
그리고, defer 에서 base를 들여오는 방법도 2가지 방법이 있습니다.
[3] from twisted.internet import base
[4] import base
[1]과 [2], [3]과 [4]는 각각 대충 보시다시피 각각 절대경로와 상대경로의 차이입니다. 그동안 권고사항으로 패키지 안에서는 꼭 절대경로로 임포트해 주세용~ 이라고 항상 말을 해 오긴 했지만, 대부분의 파이썬 사용자들이 직접 파이썬 매뉴얼을 읽고 공부하는 것이 아니기 때문에, 필드에서는 상대경로가 더 많이 통용되고 있었습니다. 그런데, 여기서 심각한 문제가 발생하는데, 상대경로 임포트가 시점에 따라서 중복으로 임포트 되어서 오작동을 하거나, 엉뚱한 것이 임포트되기도 하고, base같은 흔한 모듈은 더욱 더 큰 문제가 되곤 했습니다.
그래서, 파이썬 2.6부터는 절대경로 임포트를 강제화해서, 위의 예에서 [2]와 [4]같은 것은 이제 더이상 허용되지 않습니다. 대신, 이제 상대경로라는 것을 명시적으로 지정하는 문법이 새로 들어왔습니다.
# defer에서 base 임포트
from . import base # 같은 디렉토리
# defer에서 proactor 임포트
from .iocpreactor import proactor # 하위 디렉토리
# proactor에서 defer 임포트
from .. import defer # 상위 디렉토리
# plugin에서 defer 임포트
from ..internet import plugin # 상위 디렉토리의 다른 하위 디렉토리
파이썬 2.5b2가 며칠 전에 발표되었고, 이제 2.5 최종 릴리스가 바싹 다가오고 있습니다. 오랜만에 파이썬 2.5 미리보기를 이어서 ^^;
오늘은 라이브러리 변화를 간단하게 요점정리해 드리겠습니다~
functools 모듈
이번 파이썬 2.5에서 처음 들어오는 모듈로 PEP-309 Partial 을 포함한 functools 모듈이 있습니다. 아주 옛날에 오픈룩에서 소개해드린 적이 있는 놈입니다. (거의 알박기 식으로 구현을 해 놓은 느낌이;;) 로그를 남기거나, 함수에 들어갈 인자를 여기저기서 조금씩 주거나 할 때, 등등 아주 유용하게 쓸 수 있겠죠~ 특히 함수형 언어 하시던 분들은 반가우실 것 같습니다. ^^;
잘 생긴 AMK의 Functional How-To에서 좀 더 깊은 함수형 프로그래밍의 활용을 다루고 있으니, 읽어보세요 +_+
가장 파이썬답게 XML을 파싱할 수 있는 라이브러리인 effbot의 ElementTree도 표준 라이브러리로 들어왔습니다. 자세한 내용은 전에 블로그에서 소개해 드린 적이 있습니다. 요새 드는 생각이, BeautifulSoup도 표준 라이브러리로 들어오면 좋지 않을까 하는.. 으흐흐.. 온통 BeautifulSoup.py를 포함해서 배포하는 프로그램들이 여기저기 널려있어서;;
hashlib
전에 한번 오픈룩에서 언급한 적이 있는데, 기존의 md5, sha 모듈 등을 모두 합쳐서 통합된 API로 쓸 수 있게 hashlib이 들어왔습니다. 이제 sha-512까지도 지원하기 때문에, 아직까지는 콜리젼이 발견되지 않은 높은 수준의 해시도 선택적으로 쓸 수 있게 되었습니다.
sqlite3
요즘 전성기를 누리고 있는 파일기반 내장용 SQL 데이터베이스인 SQLite와 DB-API 2.0 어댑터 라이브러리가 들어왔습니다. 아마 대부분의 오픈소스 배포판에서는 라이브러리 의존성 때문에 별도의 패키지로 떨어져서 돌아다니겠지만, MS윈도우에서는 파이썬 인스톨러로 깔면 sqlite3 모듈을 바로 쓸 수 있게 되었습니다. (FreeBSD에서는 databases/py-sqlite3 모듈로 따로 분리하였습니다.)
wsgiref
PEP-333 Python Web Server Gateway Interface에서 정해진 스펙을 구현한 참조구현 라이브러리입니다. WSGI는 그동안 CGI,
Twisted,
Zope,
CherryPy,
mod_python 등이 모두 따로따로 서로 다른 API를 쓰고 있으면서도 비슷한 기능을 지원하고 있었기 때문에, 쓸데없이 포팅이 귀찮았던 문제를 해결하기 위해 정의된 놈입니다. 그래서, WSGI 규약만 제대로 지키면, 모듈 하나만 제대로 구현해서, Twisted에서 돌아가던 것을 mod_python에서도 돌릴 수 있고, Zope에서도 돌릴 수도 있고 여러모로 활용이 편하게 되었습니다. wsgiref는 독립서버로 작동하는 참조구현 모듈입니다. 테스트에도 간단하게 쓸 수 있겠죠~
그 외에는~
앞의 큼직큼직한 변화 외에도, 자잘한 라이브러리 버그 수정과 성능 향상, 기능 추가가 많이 있었습니다. 그 중에 뚜렷한 변화 몇 가지만 추려 보자면,
얼마 전 파이썬 마을에서 한 회원께서 파이썬 튜토리얼 없나요?라고 질문하시면서, 없으면 직접 번역하겠다고 나선 것을 계기로 해서, 번역에 대한 얘기가 꽃피고 있습니다.
그래서, 옛날에 번역된 것은 있었지만, 결국 업데이트가
유지하기가 매우 힘들어서 지금은 낡아서 소용없는 것이 되었기에
이제 제대로 번역할 수 있도록 자리를 마련했습니다.
이번에는 파이썬 svn의 리비전을 기록해 두고 업데이트되는 대로 바로 변경사항을 반영해서 항상 최신 문서가 유지될 수 있도록 하려고 합니다. 그리고 원래 문서 그대로 LaTeX 문서를 고쳐서 작업을 하는 방향으로.. :)
현재는 파이썬 마을 회원이신 jailbird 님께서 혼자 첫 부분을 꽤 번역하셨는데, 앞으로 다른 분들도 교정과 번역, 퇴고 등의 작업에 참여해 주시면 좋은 결과가 있을 것 같네요. 한국어 문서도 언젠가는 일본어 번역처럼 전체 문서를 제공할 수 있는 날이 오겠죠~
여유가 있으신 분들의 많은 참여 부탁 ^.^;
어느 정도 진행이 되고 나서, 앞부분 초벌 번역의 경험을 토대로 전체적인 번역 정책을 세워서 일관화도 해야하고 할 일이 많군요~
혹시 latex2html에서 인코딩 관련해서 잘 아시는 분은 좀 도움을; 옵션을 적당히 넣어 줘도 입력을 latin1으로 받아서 자꾸 깨지는군요;;
피드를 읽다가 BeautifulSoup 새 버전이 나왔다는 소식을 듣고, 뭐가 바뀌었는지 궁금해서
홈페이지를 가 봤습니다. 그런데, 전에 없던
cjkcodecs, iconvcodec에 대한 링크가 갑자기 생긴 것입니다.
오잉 BeautifulSoup에서 웬 cjkcodecs 링크람~ 하고 자세히 봤더니
옆에 chardet라는
인코딩을 자동으로 결정해 주는 라이브러리가 붙어있는 것입니다!
호오.. BeautifulSoup은 지금까지 취해왔던 "개떡같이 쓴 것도 찰떡같이 알아듣는다"를 충실히 지키기 위해, 이제 인코딩이 언급되어 있지 않은 문서도 마구 디코딩을 해 줄 장정인가봅니다;;
Mark Pilgrim이 만든 chardet는 작년 8월에 나온 것인데, 노가다로 일일이 디코딩해보고 결정하는 것이 아니라, 각 인코딩 별로 보통의 빈도에 대한 통계
자료를 기반으로 해서 결정한다고 합니다.
나온지는 제법 오래된 것인데, 참 신기하고 재미있네요.
이제 트랙백 받는 것도 chardet 붙여서 똑똑하게 받아 봐야겠습니다.
^.^; (통계자료는 모질라 안에 들어있는 것을 포팅한 것이라고 합니다.)
이번 내용은 직접 사이트를 운영하는 회사를 대상으로 한 것이라서, 다른 회사에 납품하거나 홍보를 해야 하는 영업적인 측면은 넣지 않고 의사 결정을 완전히 직접할 수 있는 상황에 적합하게 썼습니다. 방학 때나 언제 시간이 남으면, 의사 결정권이 없고 영업적인 고려까지 해야 할 때 파이썬을 어떻게 써야할 것인가에 대해서도 한번 써 봐야겠네요. ;;
작년에도 굉장한 인기를 끌었던Google Summer of Code가 올해도 더욱 더 커진 규모로 시행될 계획이라고 합니다. 이미 FreeBSD 프로젝트나 파이썬 소프트웨어 재단같은 멘터 기관들은 내부적으로 멘터들을 모으고 프로젝트 아이디어들을 모으느라 부산하게 움직이고 있습니다.
올해도 작년과 같이 각 단위당 학생 4500달러, 멘터 500달러로 상금을 주고 둘에게 각각 구글 티셔츠를 1벌씩 준다고 합니다;; 작년에도 프로젝트들이 대다수가 성공해서 상금을 받아간 것을 보면, 올해도 결과들이 무척 기대가 됩니다. 올해는 한국에서도 많이 참가해서 커밋로그에서 많이 보게 되었으면 좋겠네요~ 5월 1일 부터 참가 접수가 시작되고, 5월 8일에 참가 접수 완료해서 5월 22일에 멘터-학생 매치가 완료된 뒤에 발표가 나서 시작한다고 합니다.
약간 좀 거시기한 것은, 6월 말까지 중간까지 진행해서 중간 보고를 하기 때문에 한국의 학사일정하고는 안 맞아서 정작 설렁설렁 다니는 학생이 아니면 일정 맞추기가 쉽지가 않긴 한데.. 흐흐.. 아쉽네요~ (저도 7월까지 빡시게 여름학기를;;;)
lucy(perky):~/cvs/python/branches/p3yk% ./python
Python 3.0x (p3yk:43459, Mar 31 2006, 02:33:47)
[GCC 3.4.4 [FreeBSD] 20050518] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>>
으흐흐.. 어제 귀도가 p3yk 브랜치 버전을 3.0으로 올렸습니다.
그래서 이제 3.0이 확~ 다가온 느낌이군요.. ^_^;
(뭔가 꼭 학부 OS 첫 숙제들 같이 버전 고쳐서 컴파일해오기 한 것 같은 기분도 약간 -O-)
어제 릴리스된 파이썬 2.4.3으로 lang/python 포트를 업데이트 했습니다. 이번에는 얼마 전에 lang/python-devel 포트에서 시험적으로 적용했던 pkg-plist 줄여쓰기를 메인 포트에서도 한 번 적용해 봤습니다. 원래 py, pyc, pyo를 모두 pkg-plist에 적어 두고 있었는데, 용량이 너무 커져서 파이썬 포트들만 모두 합쳐도 이제 1MiB가 넘어가는 판국이 되어서 pyc와 pyo를 빼고 awk로 중간에 처리를 하도록 해버렸더니 60KiB정도가 줄었습니다. :) 그리고, NO_NIS는 있으면서도 PORTMAP은 안 끈 시스템에서 설치하다가 파일이 없다고 에러나는 것도 rpcgen 대신 ypcat을 체크하도록 해서 고쳤습니다.
파이썬 2.4.3은 아주 마이너한 버그 패치들만 들어가 있기 때문에, 기능적으로는 특별히 볼 만한 것은 없지만, Coverity와 refleak check, buildbot 등 파이썬 개발팀에서 최근에 사용하기 시작한 완성도 높이기 덕택에, 자잘한 버그들이 정말 많이 수정되었습니다. (예를 들어 PyObject_Unicode(NULL) 하면 세그폴트 나버리는 문제라던지..) 완성도 관련이나 릴리스 자동화, 막판의 버그 픽스와 하위 호환성의 충돌과 관련해서 좀 더 깊숙히 할 얘기가 있는데 2.4.3 릴리스와 관련된 뒷얘기들은 다음 기회에 다시 자세히~
그나저나, 지금 확인해 보니 아직 넷비, 우분투, 젠투, 데비안, 페도라에는 2.4.3이 안 들어간 걸 봐서는 이번엔 프비가 대략 1등? ^_^;; =3=33 (시험 전날 공부는 안 하고 이런거나 --;;)
파이썬을 파이썬으로 주로 구현하는 야심찬 프로젝트인 PyPy 프로젝트는 뭔가 계기가 되는 굵직한 작업들이 주로 개발자들이 오프라인에서 모여서 스프린트를 하면 뭉터기로 해결이 되는 특징이 있습니다. 무협 영화에 보면 자주 나오는, 숨어있던 고수들이 어느날 갑자기 여기 저기서 흘러들어와서는 중원의 잡배들을 물리치고, 휙하고 사라지는.. 마치 그런 장면! (.. 괜히 흥분;;) 요즘은 우리나라의 서상현씨와 서지원씨도 참여하고 있어서 무척 흥미로운 프로젝트이지요.
그런데, PyPy 스프린트는 지금까지 거의 유럽에서 하고 가끔 미국에서도 했었는데, 이번에 처음으로 엉뚱하게 도쿄의 "아키하바라"에서 하기로 했다고 한다뇨~ 역시나 일본에서 하는 것이라 지난번 아시아 코드페스트에서 굉장한 지원을 해 주었던 FSIJ (Free Software Initiatives in Japan)에서 지원 해준다뇨~ 일본에 사는 파이썬 해커들 뿐만 아니라 많은 수의 유럽 해커들까지도 지원을 받아서 참가하는 것 같다뇽~ (;;)
게다가 이번 스프린트 주제 1번이 Squeak VM 백엔드에다가 PyPy를 올린다고 하니.. 특히 스퀵이 강세인 일본에서 많은 해커들이 활발히 참여할 것 같아서 무척 재미있을 것 같습니다. :) 아 역시 옆에 있는 나라 사람으로써 우리나라에서도 한 번 했으면 싶지만, FSIJ처럼 돈 많이 쓰는 곳이 없어서 약간 아쉽네요. ^_^;
파이썬 2.5에서는 C API 청소가 약간 있었습니다. 그동안 문제로 지적되어 왔었던 const가 지정되지 않은 API 인터페이스의 문제들과, 크기를 지정하는 타입으로 int에서 Py_ssize_t로 바뀐 것이 대표적입니다.
const 문제는 PyString_FromString 같은 함수들이 문자열을 char *타입으로 받는데, const char*이 아니기 때문에, 일반적인 문자열 상수를 막 던지려면 경고를 피하려고 캐스팅을 해야하는 문제가 있었습니다. 물론 아예 그냥 상수로 선언을 안 하면 data 영역으로 떠서 메모리에 올라올 때 낭비도 있고요.. 그래서 이번에 const가 쫙 달려서 이제 깔끔하게 쓸 수 있게 되었습니다.
그리고, 그동안 크기를 지정하는 타입으로 int를 사용해 왔었는데, 그 때문에 문자열이나 리스트의 길이가 2^31자/개 까지로 제한되어 왔습니다. 이게 64비트 플랫폼에 가면서 문제가 됐는데, 따라서 플랫폼에 맞는 크기 지정 타입으로 내부적으로 Py_ssize_t를 선언해서 쓰기 시작하였습니다. 덕분에 대부분의 타입들이 64비트의 주소 영역을 충분히 활용하게 되었구요~
그런데, 하나 문제가 생겼습니다. API에서 주소 크기가 문제가 되는 경우, 즉 PyArg_ParseTuple 같이 가변인자를 동적으로 읽어오는 경우에 64비트가 올 자리에 32비트가 오고 그러면 포인터가 막 쭉쭉 밀려서 세그폴트가 나게 됩니다. 이 문제를 해결하기 위해서 그냥 디폴트로는 옛날처럼 int 타입하고 최대한 호환되게 남겨두고, PY_SSIZE_T_CLEAN 이라는 매크로를 Python.h가 포함되기 전에 정의가 되어 있으면 z# 같은 포맷까지도 모두 Py_ssize_t를 사용하도록 하였습니다.
파이썬 C API에서 가장 노가다성이 짙어서 과연 얼마나 심심해야 이런 것 할 시간이 날까 하고 생각하고 있었던 청소가 모두 끝난 것이라 무척 상쾌한 릴리스가 될 것 같습니다. :)
오프라인 파이썬 서적 중 좋은 것을 추천하자면, 프로그래밍 입문자용으로는 당연히
《Python Programming for the Absolute Beginner》를 추천하겠지만, David Beazley의 책이 막강하게 지키고 있던 기존에 다른 언어를 쓰던 프로그래머들을 위한 것으로는 David Beazley책이 한물간 이후로는 적당한 것이 딱히 없었습니다.
1판에는 귀도가 추천사를 쓰기도 했던 Beazley의 《Python Essential Reference》는 굉장히 간결한 설명으로 이미 다른 언어에서 뿌리를 내리고 있는 사람들이 옆으로 곁가지 치는 식으로 파이썬을 배우기에는 정말 좋은 놈이었습니다. 그런데 파이썬 책들이 갖게되는 공통적인 문제점.. 파이썬 버전이 올라갈 때마다 문법이 계속 새로 나와서 옛날 버전 책을 사기가 굉장히 난감하다는 것 때문에, 2판이 2.1에 맞춰서 나오자 마자 2.2가 나와버린 이후로 역사의 뒤안길로 미뤄져 있었던 것이었습니다. 이번에 드디어 2.4용으로 업데이트가!
Types and Objects in Python이라는 챕터가 샘플로 올라와 있습니다. 보니까 드디어 isinstance도 다루고 있고, 부담없이 추천할 수 있게 되었네요. :) 그렇지만.. 이번에도 이 책의 운명은 참 불쌍합니다... 2.5가 곧 나올텐데.. ㅠ.ㅠ
C의 ? : 이른바 삼항연산자라고 부르는 그 놈은 C에서 파이썬으로 넘어오는 개발자들이 항상 목말라하는 그런 것이었습니다. 그래서, 궁한대로
1) a == b and 1 or 0
2) [0, 1][a == b]
3) (a == b and [1] or [0])[0]
4) {True: 1, False: 0}[a == b]
등 별 희한한 방법을 다 쓰고 있었지만, 1번은 제약사항이 있고, 2,3,4번은 눈에 확 들어오지 않는다는 치명적인 문제가 있어서, 결국은 if: else: 해서 4줄로 나눠써야 했었습니다.
이 문제 해결을 위한 여러 사용자들의 꾸준한 요청으로 귀도가 드디어 투표를 하기로 결심해서, 2003년에 투표를 해서 결정이 되긴 했지만, 여러 분파로 나뉘어서 그 후에도 좁혀지지 않는 의견차로 인해서 실행이 될 기미가 보이지 않았습니다. 그래서 결국 1000000표를 행사하는 귀도가 모든 사람이 상상도 못했던 희한한 문법을 들고 나와서 그걸로 결정해 버렸습니다. (이런 일은 print >> None 때도 다들 황당했었지요.. ;;)
결정 문법: X if COND else Y
X가 맨 앞에 나오지만 X가 먼저 해석되지도 않을 뿐더러, COND가 중간에 숨겨지고, X와 Y가 떨어져있는 등 귀도 외에는 좋아하는 사람이 거의 없는 듯 했지만, 어쨌거나 이 문법으로 결정이 되었습니다. 그 문제는 구현까지 완료돼서 들어오고 나서 더욱 더 강조가 되게 되었는데,
text = data if logging else ''
이렇게 쓰면 다른 언어들의 if, else 문법들의 영향으로 다음 중 어느 것으로 해석되는지가 굉장히 헷갈립니다.
1) (text = data) if logging else ''
2) text = (data if logging else '')
물론, 파이썬에서는 1번이 기본 구조로 불가능하기 때문에 2번이 정답이기는 하지만, 다음과 같이 꼭 띄어써야 하는 부분이 아니면 안 띄어쓰는 (약간은 ㅂㅌ스러운 ㅎㅎ;) 코딩 컨벤션을 쓰는 사람이라면 훨씬 더 난감해집니다.
text=data if logging else ''
으흐흐.. 하여간, 이 문법이 과연 파이썬 3.0까지 살아남을 수 있을지 두고 봐야겠습니다. "print >> file" 처럼 처음에는 다들 굉장히 싫어했지만, 결국에는 다들 익숙해져버리는 쪽으로 될 지도 모르겠고요..
선 코딩 후 테스트식 개발을 할 때에는 커버리지 분석 도구가 꼭
필요합니다. 상용 커버리지 분석 도구 중에서는 파이썬 코드도 예쁘게
분석 결과를 보여주는 것이 있었는데, 아직 오픈소스 도구 중에서는 딱히 마땅한 게 없었는데요, 드디어 하나 제대로 예쁜게 나왔군요.
trace2html! 출력 예시를 보면 trac과 함께 파이썬기반 프로젝트들이 꼭 설치해야 할 프로그램이 하나 늘었네요~ :) (trac 플러그인으로 들어가길!)
비주얼 스튜디오나 델파이/C++빌더 같은 윈도우 기반 IDE들에 익숙한 개발자들이 쓸만한 IDE도 하나 발견했는데, PyScripter 상당히 예쁘군요. 아무래도 델파이 개발자들 눈에 맞춰서 만든 컴포넌트들을 그냥 그대로 갖고 와서 쓰다보니 그렇게 된듯~ 단, 델파이로 되어 있기 때문에 IDE를 고친다거나 포팅한다거나 하는 것은 굉장히 어렵겠습니다. 스크린샷
요새 파이썬 2.5 릴리스 엔지니어링 시작이 임박하면서 여러가지 새로운 소식이 나오고 있어서 몇가지 전해 드립니다. :)
파이썬 홈페이지 디자인 변경: 아직 완전히 끝난 것은 아니지만 전체적인 디자인이 회사스럽게 바뀌었습니다. 아무래도 투박한 오픈소스 프로젝트형 디자인에 익숙하지 않은 경영진들에게도 신뢰감을 줄 수 있겠죠.. :) 보면서 하나 눈여겨 볼 수 있는 부분은 화면 아랫쪽의 구글광고입니다. 일반적인 구글 애드센스가 아니라, 구글 애드센스에서 곧 도입할 예정인 탭 광고를 테스트 중이라고 합니다. 한동안 저 자리에 MS Visual Basic 광고가 나왔던 적이.. 흐흐;
파이썬 3000 프로젝트 시작: 귀도가 드디어 svn 저장고에 파이썬 30000 브랜치를 만들었습니다. 이름이 py3k가 아니라 p3yk입니다. -O-;;; 아직은 활발한 개발이 시작된 것은 아니고, 구글에서 50% 자유시간의 대부분을 파이썬 3000에 쓴다고 하니까 기대가 되는군요~ 지금 현재로써는 with문 future만 제거된 것이 들어가 있습니다.
PSF 블로그 개설: 파이썬 소프트웨어 재단의 블로그가 개설되었습니다. 재단에서 행사 조직과 관련해서 많은 일을 하고 있는 amk가 주로 쓰게 될 것 같군요. 지금 현재는 PyCon관련 설문 같은 것이 올라와 있습니다. :)
파이썬 2.5 릴리스 일정: 파이썬 2.5 릴리스 코디네이터가 Neal Norwitz로 결정되었고, 4월 1일부터 알파 1 릴리스를 시작해서, 8월 19일에 최종 릴리스를 하는 것으로 일정이 잡혔습니다. 2.4에 비해서 굉장히 많은 것이 바뀌기 때문에, 아주 설레입니다. ^.^
Coverity 체크: 최근에 스탠포드에서 나와서 별도의 회사가 된 Coverity에서 여러 오픈소스 프로젝트들의 static analysis 결과를 제공해주었습니다. perl쪽에서는 처음에 coverity에서 경고한 버그 수가 적다고 그걸 기사로 쓰는 곳까지 있었는데, 파이썬 개발자들이 재빠르게 대응해서 곧 펄의 1/2 이하로 줄여서 최저 1000라인 코드당 0.01개의 버그 경고로 줄였습니다. (최근 ctypes 임포트 이후에 30개 정도가 새로 들어와서 좀 늘었습니다;;)
일본 파이썬 유저그룹에서 4월 8일에 Python Workshop the Edge 2006을 개최한다고 합니다. 일본그룹에서는 2005년부터 대략 3~4개월에 한번씩 워크샵을 주기적으로 개최하고 있는데, 하루 저녁동안 하는 것이기 때문에, 왠지 한국에서 워크샵 그러면 여러 날 할 것 같지만 그런 규모는 아니고, 좀 큰 규모의 스터디 그룹 정도로 보입니다.
일본의 파이썬 워크샵은 장소가 아주 독특한데, "마이크로소프트 본사"랍니다. 물론 미국의 본사는 아니고, 일본 마이크로소프트의 본사겠지만, 전통적으로 이런 행사를 지원하는 아스키 출판사 같은 곳이 아니라 마이크로소프트가 지원하는 이유는 도대체 무엇일까! --- 바로 이번 워크샵의 마지막 세션에 힌트가 있습니다. 일본 MS 직원이 직접 IronPython에 대해 발표하는 것입니다! IronPython을 미국 본사의 CLR 팀에서 Jim 혼자서 삽질을 하는 것이 아니라, 일본에서도 전략적으로 의미를 두고 있고 커뮤니티 지원을 한다는 점이 상당히 인상적입니다. (참고: IronPython은 마이크로소프트에서 BSD 라이선스로 배포하는 .NET기반 파이썬 구현입니다.)
그 외의 다른 세션들로는 kizasi라는 요새 일본에서 유명한 블로그 통합 사이트의 개발자가 파이썬으로 사이트를 구축한 사례에 대해서 발표하고, 튜토리얼 세션 하나, SkypeJapan에서 Skype 파이썬 API에 대한 발표를 합니다. 그리고, 요새 파이썬 관련 모임이라면 어디서나 항상 나오는 웹 프레임워크들 Django, TurboGears과 비교적 덜 알려진 web.py에 대해 패널 토론이 있다고 합니다.
파이썬 2.5의 또 다른 주요 변화로 소개해 드릴 만한 것으로 incremental codec이 있습니다. 파이썬 유니코드 코덱의 기존 스펙에 대한 확장인데, 논의되는 과정 중에 여러가지 난관이 있었습니다. 확장이 쉬운 디자인이 어떤 것인가, 확장이 어려운 디자인을 택했을 때 나중에 확장을 어떻게 할 것인가에 대한 좋은 사례가 될 듯 합니다.
파이썬 2.0에서 처음 들어온 PEP-100 유니코드 통합에서는 4가지 코덱 방식을 정의하고 있습니다. 인코더, 디코더, 스트림 인코더, 스트림 디코더 입니다. 인코더와 디코더는 상태가 없는 (stateless) 단순 문자열 변환을 담당하고, 스트림 인코더와 스트림 디코더는 파일같은 스트림들에 대해서 상태가 있는 (stateful) 변환을 담당합니다.
얼핏 보면 상태가 있는 것도 있고, 없는 것도 있으니 괜찮은 디자인이 아닌가 하고 생각을 할 수 있는데, 파이썬 2.0이 릴리스 되고 나서, 그 이후에 JapaneseCodecs나 KoreanCodecs가 나오면서 문제가 발견되게 됩니다. 바로, 상태가 있는 문자열 변환을 할 수가 없다는 것입니다. 상태가 있는 변환을 하기 위해서는 스트림을 거쳐야하기 때문에, 엉뚱하게 계속 StringIO같은 것을 끼고 들어가야 하게 되어서, 번거롭기도 하고 느리기도 하고 아주 기분 나쁜 상황이 되어 버립니다. 게다가, 스트림은 끝이 단 하나만 존재하기 때문에, 현재 버퍼에 있는 미완성 부분을 완성하려고 파일 끝으로 표시해 버리면 더 이상 쓸 수도 없고 상태도 잃어버리는 문제도 있었습니다.
여기서 알 수 있는 디자인의 교훈은, 다른 언어에 있는 걸 무작정 따라하기 보다는, 해당 도메인에서 할 수 있는 작업들을 나열한 다음에, 각 작업들이 공통으로 가지는 최소한의 요소들을 뽑아서 그것들로 다른 작업들을 구성해 보면 좋겠다는 생각입니다. 간혹 어떤 라이브러리를 쓰다 보면, 한 함수의 극히 부분적인 기능이 필요한데, 더 작은 함수가 없어서 결국은 함수의 쓸데없는 다른 부분까지도 모두 에뮬레이트 해야 하는 경우가 있습니다. 그럴 때는 답답하고 억울해서 산에 가서 임금님 귀는~~ 이라도 하고 싶은 경험을 할 때가 있는데, 그 때의 경험을 마음 깊이 새겨서 그런 라이브러리를 안 만들도록 해야겠네요. :)
(얘기가 딴 데로 빠져서 다시 원래대로 오자면~) 그래서, 그동안 파이썬에서 여러모로 문제가 많았던 UTF-8 스트림 디코딩이 결국은 내부적인 상태 제어 함수를 만들어서 해결이 되었고, 애플리케이션들도 쉽게 이런 것을 쓸 수 있게 유니코드 스펙을 확장해서 기존의 4개에 2개를 더해 incremental decoder, incremental encoder가 추가되었습니다.
그런데 여기서 발생하는 또 하나의 디자인 문제! 코덱을 찾아 주는 codecs.lookup라는 함수는 위에서 언급한 4개를 tuple로 리턴해 주는 방식으로 되어 있다는 것! 그래서 결국은 이번에 새로 추가된 2개를 더하면 tuple의 크기가 바뀌어서 사용자 코드들이 하위호환성이 없어진다는 치명적인 문제가 생깁니다. codecs.lookup을 왜 public API로 공개해서 이런 문제를 만드냐~ 하고 이런 저런 서로 원망을 하다가 결국은 os.stat에서 쓴 트릭으로 처리가 되었습니다. 즉, 객체를 따로 하나 만들어서(codecs.CodecInfo) tuple 쓰듯이 접근하면 옛날처럼 4개를 돌려주고, 하위 속성을 접근하면 이름으로도 접근할 수 있게 하는 것입니다. 예를 들어, c = codecs.lookup('cp949') 일 때, c[0]부터 c[3], len(c) 하면 옛날 tuple 쓰듯이 흉내를 내고, c.incrementalcodec 이나 c.encoder, c.streamwriter 같은 방법으로 새로운 API를 쓸 수 있게 하였습니다.
>>> import codecs
>>> dec = codecs.lookup('cp949').incrementaldecoder() # cp949 상태있는 디코더를 만듦
>>> dec.decode('한글') # 그냥 상태 없는 디코딩이나 마찬가지
u'\ud55c\uae00'
>>> dec.decode('한글'[:3]) # 마지막 1바이트 빼고 넣음
u'\ud55c'
>>> dec.decode('글'[1:]) # 남은 1바이트를 마저 넣어서 완성
u'\uae00'
>>> dec.decode('한글'[:3]) # 다시 첫 3바이트를 넣음
u'\ud55c'
>>> dec.decode('', True) # 버퍼에 '글' 앞쪽 바이트가 있는 것을 flush
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'cp949' codec can't decode byte 0xb1 in position 0: incomplete multibyte sequence
>>> dec.reset() # 버퍼를 초기화
>>> dec.decode('', True) # 버퍼를 초기화했기 때문에 비어있음
u''
cp949는 사실 좀 밋밋하긴 한데, 살 떨리게 재미있는 ISO-2022로 한 번 해 보면..
>>> dec = codecs.getincrementaldecoder('iso2022-jp')() # 이게 더 좋은 방법
>>> ESC = '\x1b'
>>> dec.decode(ESC+'(') # G1 캐릭터셋 할당 시퀀스 앞부분
u''
>>> dec.decode('J~~') # 0201로 할당
u'\u203e\u203e'
>>> dec.decode('J~~') # 이제 앞의 J는 이스케이프가 아님
u'J\u203e\u203e'
>>> dec.decode(ESC+'$B$@') # G1을 0208로 바꾸고 1글자
u'\u3060'
>>> dec.decode('$@$@$') # G1에서 2글자 더 진행하고 반은 남김
u'\u3060\u3060'
>>> dec.decode('@'+ESC+'(BABC') # 0208에서 마지막 완성하고 ascii에서 3글자
u'\u3060ABC'
처음에는 이런 것을 지원해 주기 위해서 incremental codec이 아니라 feed style codec이라는 것이 나왔었는데, 뭔가 부자연스러워 보이는 것이 관련있는 사람 대부분이 답장도 안 올리고 바쁜 척을 했었습니다. 그런데, 새롭게 incremental codec이 나오고 나니까 다들 훨씬 깔끔하다고 칭찬을! 으흐흐. 아무래도 문제 해결을 억지로 라도 한 번 해 보고 나면, 훨씬 더 좋은 다른 방법을 발견하기도 쉽다는 것도 있겠고.. 다른 사람들이 바쁜 척하는 것 같으면 잘 눈치를 채야 한다는 뭔가가... -o-
다음 시간에는 뜨거운 감자였던 조건적 표현식(C에서 보통 삼항 연산자라고 부르는 그것)에 대해서~
PyCon 2006이 끝나면서 스프린트의 결실이 속속 올라오고 있습니다.
귀도보다 더 파이썬을 잘 안다고 말할 수 있는 몇 명 중의 하나인 팀 피터스는 이번 스프린트에서 파이썬 메모리 관리 시스템을 작업해서 드디어 끝을 냈다고 합니다. (팀의 얼굴이 궁금하시면, 위의 pycon 홈페이지에 보면 앞에 나오는 사진에서 왼쪽부터 순서대로, 귀도, 팀, (떼), 배리, 짐 입니다.)
스택에 객체 할당을 하지 않는 언어들의 속도에 가장 치명적인 부위 중의 하나가 바로 객체를 위한 힙 할당 부분인데, 파이썬은 이 문제를 해결하기 위해서 2.3부터 pymalloc이라는 것을 넣어서 비슷한 크기로 할당하는 메모리들을 풀로 관리해서 한꺼번에 크게 할당하고, 해제되더라도 pymalloc 측에서 다시 풀에 넣어서 관리를 하는 방식을 취하고 있습니다. 따라서, 시스템 라이브러리 측의 힙 관리가 단순해 지고, 메모리 단편화(fragmentation)가 줄기 때문에, 대략 20~30% 정도의 속도 향상이 있었습니다.
그런데, 이 문제가 또 다른 문제를 불러 일으키는데, 메모리 해제가 일어나더라도 pymalloc은 메모리를 시스템의 free함수로 해제하지 않고 그냥 스스로 계속 다 가지고 있기 때문에, 메모리를 먹기는 먹지만 절대로 뱉지 않는.. 마치 집을 늘일 수는 있지만 줄여서 살 수는 없다는 것을 몸소 실천하는 태도를 보입니다. 그래서, 임시로 100만개짜리 리스트를 만들었다가 삭제하면 그 리스트에 쓰려고 할당한 메모리가 계속 쫓아다녀서, 오랫동안 파이썬이 돌아가면 메모리가 모자라는 시스템에서는 난감한 상황이 옵니다. 그래서, 결국에는 소형 시스템에 들어가는 경우에는 pymalloc을 빼라는 매뉴얼이 부지기수로 나올 정도가 되었습니다.
여러 사람들이 도대체 왜 메모리가 늘기만 하고 줄지는 않느냐! 파이썬 메모리 새는 것 아냐! 하고 굉장히 주기적으로 따졌는데, 답장은 어쩔 수 없다 우리가 하는게 가장 간단하고 빠른 방법이다, 그것 싫으면 pymalloc 빼고 컴파일해라.. 이런 답장들로 일관 했었습니다. 그러던 중, 2005년 PyCon에서 Evan Jones라는 사람이 "잔다르크처럼 나타나"서는(여자라는 말은 아닙니다;;) 체계적인 설명과, 설명에 따라 구현한 패치의 벤치마크까지 들고 와서 발표하는 사건이 일어났습니다. 그래서, 그동안 몰라요~ 하고 있던 파이썬 개발자들이 번쩍 하면서 이 패치를 긍정적으로 검토하기로 했고, 이번에 이렇게 마무리 되게 된 것입니다.
결과적으로, 이제 숫자 1000000개가 들어가 있는 리스트를 할당했다가 풀면 메모리가 줄어듭니다. FreeBSD에서는 phkmalloc이 또 내부적으로 하는 짓이 있어서 윈도우에서처럼 극적으로 줄어들지는 않는데.. 그래도 저거라도 줄어드는게.. :)
그 원리는 자료구조를 공부하신 분이면 쉽게 예상할 수 있듯이, 객체 해제가 일어날 때 메모리 풀이 다시 프리 리스트에 추가되면서 아레나가 완전히 비게 되면 메모리를 해제하는 구조로 일어납니다. 역시 C 언어로 되어 있는 터라, 모든 포인터를 모두 따라가서 고칠 수는 없기 때문에, 듬성듬성 차 있는 아레나들을 정리하기 위해서 적극적으로 풀을 모으는 등의 행동은 어렵습니다. 그 문제를 해결하기 위해서 이 패치에서는 그냥 많이 차 있는 아레나들을 풀 프리 리스트의 앞쪽에 가도록해서, 많이 찬 것을 먼저 채우도록 한 것으로 보입니다.
이제 파이썬에 새로운 것이 계속 들어와도 놀라지 않을 만큼, 파이썬은 끊임없이 새로운 문법이 매 버전마다 들어오고 있습니다. 파이썬 2.3에서 generator/bool, 2.4에서 generator expression이 하이라이트였다면, 2.5에서는 단연 PEP-343 with 절이 가장 주요한 문법의 변화가 되겠습니다.
with 절은 이미 다른 언어에 많이 소개가 되어 있는 개념을 구현하기 위한 것인데, ruby의 block이나 자바의 synchronized 같은 것들과 비슷한 개념을 지원합니다. 그렇지만, 비주얼 베이식의 with같이 네임스페이스를 줄이는 목적으로 쓰는 것은 아니기 때문에 서로 다릅니다.
as VAR 부분은 생략이 가능합니다. 이렇게 쓰면 내부적으로 다음과 같이 번역이 되어서 실행이 되게 됩니다. (소문자로 된 변수들은 VM 내부적인 변수이므로 소스코드에서는 접근 가능하지 않습니다.)
ctx = (EXPR).__context__()
exit = ctx.__exit__ # 아직 호출하지는 않음
value = ctx.__enter__()
exc = True
try:
try:
VAR = value # "as VAR"이 있을 경우에만
BLOCK
except:
# 여기서 예외 처리를 함
exc = False
exit(*sys.exc_info())
finally:
# 지역적이지 않은 분기는 여기서 처리함
if exc:
exit(None, None, None)
번역 부분을 약간 살펴보면 새로운 메쏘드 이름인 __context__, __exit__, __enter__를 쓰고 있습니다.
with x as y: 라고 쓰면 x.__context__()를 호출한 다음,
그 녀석이 리턴한 객체의 __enter__()를 호출해서 리턴된 것을
y에 넣어줍니다. 단, with절은 블럭 안에서 프레임이 생성되지 않기 때문에
y의 유효영역은 with절 안이 아니라, 외부의 지역 네임스페이스입니다. (밑줄 쫙~)
자.. 과연 이런게 어디에 쓸모가 있을까! 생각해 보면, 당장 생각 나는 것은 임시 파일을 생성했을 때 귀찮게 finally로 감싸서 파일 지워주는 경우가 생각납니다. 그런데, 이런 사용 사례들을 일일이 위와 같이 __context__, __enter__같은 것을 다 구현해 주기는 굉장히 귀찮기 때문에, 실제로는 제너레이터로 간단하게 구현할 수 있도록 contextlib이라는 모듈이 신설되었습니다. contextlib에는 contextmanager라는 데코레이터가 있어서, 제너레이터를 구현할 때 @contextmanager를 통과시켜 주면 쉽게 with용 컨텍스트매니저로 변신을 시켜 줍니다. closing이라는 것도 있어서 with를 벗어나면 자동으로 파일 닫게도 할 수도 있고요~
한 번 시험해 보기 위해서, 대표적인 with절 예상 사용 사례인 SQL 데이터베이스의 트랜잭션 처리 부분을 한번 해 봤습니다. :)
from __future__ import with_statement
from contextlib import contextmanager
import MySQLdb
@contextmanager
def mysqlconn(hostname, username, password, database):
conn = MySQLdb.connect(hostname, username, password, database)
curs = conn.cursor()
try:
curs.execute('BEGIN')
yield curs
except:
curs.execute('ROLLBACK')
raise
else:
curs.execute('COMMIT')
finally:
conn.close()
with mysqlconn('localhost', 'user', 'passwd', 'db') as curs:
curs.execute('select count(*) from schedule')
print curs.fetchone()
with절에 진입하면서 자동으로 데이터베이스 접속을 맺어주며, 안에서 예외가 발생하면 롤백하고, 예외가 발생하지 않고 빠져나오면 자동으로 커밋하게 해 줍니다. 이와 비슷하게 threading.Queue같이 쓰레드 간 동기화나 임시 객체가 생성되는 온갖 사용처에 아주 유용하게 쓰일 수 있을 듯 합니다~ (위 예제를 유심히 보시면 with절 외에도 2.4에서는 안 되던 문법이 2가지 숨겨져 있습니다. 이히히히~)
그런데, with는 새로운 키워드이기 때문에, 2.5에서는 from __future__ import with_statement를 해야지만 사용할 수 있고, 2.6부터는 정규 키워드로 지정될 예정입니다.
자, 이제 파이썬이 프로그래밍을 안 해본 사람도 하루만에 배울 수 있는 언어라는 굴레에서 해방되었습니다. -O-;;;;;
파이썬 IDE로는 BoA 건설역군^^이나 상용인 WingIDE 같은 것들이 대표적입니다. 파이썬에 포함된 IDLE도 있지만, 다른 IDE 들에 비하면 IDE라기 보다는 그냥 에디터와 커맨드라인을 합쳐놓은 것 정도라고 할 수 있겠지요.
그동안 파이썬 IDE가 좋은 것이 잘 안 나오는 이유는 무엇인가! 에 대해 돈이 안 돼서 안 나온다, 사용자가 별로 없어서 안 나온다 등등 여러가지 분분했는데, Thinking in Java/C++/Python 씨리즈로 유명한 브루스 엑켈씨가 새로운 의견을 내놓았는데, 제법 설득력이 있군요.
파이썬은 이미 입력할 것들이 충분히 짧기 때문에, 자바같이 1000타 코더가 배출될 정도로 입력할 필요가 없어서, IDE가 생산성 향상에 별 필요가 없다는 주장입니다. dir()만 해 보면 뭐가 있는지 대충 보이고, 인터랙티브 모드에서 시험해 보면 오토 컴플리션 없이도 나름대로 편하게 개발할 수 있다는 것입니다.
물론, 뭐 있어서 나쁠 것은 없겠지만, 저도 아직까지 eclipse PyDev가 좋다는 말만 듣고, 아직까지도 별로 쓸 생각은 안 드는게.. 뭐시기가 거시기 한 것 같네요~ 므흐흐...
그렇지만... wxPython의 노가다 앞에서는 무력해지는 파이썬의 생산성.. -.- wxPython을 위한 완벽한 IDE에 목이 말라요!
늘 열리던 워싱턴DC가 아닌 텍사스에서 열리는 PyCon 2006이 1주일 앞으로 다가왔습니다. 작년까지는 거의 항상 3월 중순에서 말 사이에 했지만, 올해는 2월에 하게 되었습니다.
간단하게 올해의 PyCon 하이라이트를 정리해 보자면,
올해의 키노트는 24일에 Plone 개발자들, 25일에는 귀도가 "파이썬의 현상태"에 대해, 26일에는 파이썬으로 된 프로그램 중에 가장 많은 엔드유저를 확보하고 있는 BitTorrent의 Bram Cohen씨가 하게 됩니다. 이 중에서, Cohen씨는 독특하게도 기조연설을 인터뷰 방식으로 하겠다고 하고 있어서, 참가자들이 미리 질문을 올려 놓으면 그에 대해 대답하고 덧붙이는 방법으로 하겠다고 합니다. 재미있을 것 같네요. :-)
강연/연설 들은 상당히 많은 세션이 배정되어 있는데, 작년에 비해서 꽤 늘어난 것이 파이썬 개발자들의 수가 확실히 늘고 있는 느낌이 듭니다. 작년 PyCon과 OSCon에서 상당히 인기를 끌었던 IronPython 세션의 후속편도 준비되어 있는데, 이번에는 Hugunin씨의 implementation 세션 외에도 MS의 다른 직원의 .NET 스크립팅 발표도 있습니다. 그리고, 웹 프레임워크 계에서는 역시 TurboGears와 Django, Zope 모두 마련되어 있고, 23일에도 상당히 많은 시간이 배정돼 있어서 역시 열띤 토론과 스프린트가 있을 듯 합니다.
그리고, PyPy의 구조에 대한 세션, Stackless의 사례, reST, docutils 같은 늘 나오던 사람들도 나와 있고, 사업에 파이썬을 사용하는 것, 엠베디드에서의 활용 사례, 노키아 S60의 사례 같은 것에 대한 발표도 있습니다.
작년 대안언어축제에서도 했던 OST를 위해 공간이 마련되어 있는데, 작년 PyCon 사진을 보고 우루루 바닥에 앉아 얘기하는 것들을 부러워했었는데, 올해도 PyCon에서 재미있는 이야기가 많이 나올 것 같아서 참 아쉽게 되었네요. :-)
이번에는 RVSP로 실황 중계도 있고 녹화도 할 예정이라고 하니까, 직접 참가하지 않더라도 현장의 상황을 볼 수 있어서 무척 좋을 것 같구요. 24일에는 모여서 보드게임도 한다고 합니다. :) 그리고 참가자들 중에서 워낙 유명한 사람이 많다보니, 키사이닝 파티가 아니라 북사이닝 파티를 할 수 있을 정도라고 하니까 참 부럽군요~
PyCon의 더 자세한 이야기는, 곧 PyCon에 참가하러 텍사스로 떠나시는 OSK의 이만용이사님께서 돌아오시면 파이썬마을 번개를 한번 해서 듣는 자리를 마련 하도록 하겠습니다~ ^^
지난 학기에 복학하는 기념으로 좋은 시간표를 만들어보고자
시간표 최적화 프로그램을 만들어서 열심히 돌려서 한 학기를
널럴한 시간표에 즐겁게 보냈습니다.
그래서 이번 학기도 어떻게 좀 더 삶을 이롭게 하고자 한번 돌려
봤는데, 글쎄 학교에서 웹 디자인 수정을 하나도 안 하는 바람에
연도만 바꾸니까 바로 돌아가는!.. 한편으로는 너무 시시하게 끝나서 실망한 나머지, 괜시리 일거리를 만들어서 GUI 공부를 한번 해 봤습니다. 그래서 이번에는 wxPython 버전으로 껍데기를 씌웠습니다. ^^ (기왕이면 누구나 쓸 수 있는 윈도우용 GUI 프로그램으로~)
사실 파이썬은 오랫동안 해왔지만, 그동안 GUI에는 관심이
전혀 안 생겨서, wxPython이고 Tkiner이고 "Hello, World!" 버튼 1개 있는 것
말고는 만들어 본 적이 없는데~ GUI 툴킷을 배워서
써먹어 보고 싶은 마음에 둔 곳이 하나 있어서, 간단한 것
해보려고 해봤습니다. 그런데, 생각보다 훨씬 삽질이네요. -O-;
파이썬이라고 간단하다더니 이런 삽질을!!!
시간표 프로그램으로 돌아가서ㅡ. 저기 보이는 그리드 박스에
학정번호와 선호도, 그룹을 입력해 주면, 자동으로 학교
홈페이지에서 시간표와 학점을 긁어와서 가능한 모든 시간표
배치를 시도하여 최고 점수의 시간표를 HTML로 뽑아주는 프로그램입니다. 컴과 학생들은 다들 한번씩은 생각해봤음직한~ 으흐;;
얼마 전, 2.4에 들어온 itemgetter, attrgetter와 2.5에 들어온 partial과 비슷한 새로운 제안으로 methodcaller라는 obj.meth(*args, **kwds) 를 줄여쓸 수 있는 뭔가를 만들자고 제안이 올라왔었습니다.
그에 대한 대답으로, FreeBSD의 bikeshedding 만큼이나 Python-Dev에서는 전통적인 여러 사람이 별의 별 희한한 자기 입맛에 맞는 문법을 마구 올려놓고, 서로 여기저기 투표하기만 하고 결론이 안 나는 상황이 꽤 오랫동안 있었습니다. lambda 를 더 짧게 쓰는 방법을 만들자, 그런 것 자꾸 만들면 복잡하다 그냥 def 하자, def를 리턴하는 키워드로 만들어서 안에 집어넣자 등등.. 나올 수 있을 만한 얘기는 거의 다 나왔습니다.
이에 대한 귀도의 답변: Let's just *keep* lambda -- Python 3000에서 lambda와 함수형 프로그래밍 함수들을 빌트인에서 빼려는 계획을 귀도가 그동안 여러번 언급을 했었는데, 그냥 lambda를 유지하고 다른 문법 논의는 다들 수긍할 만한 대안이 안 나왔으니 앞으로는 얘기하지 말자는 결론을 올렸습니다.
그동안 귀도의 눈치를 보며 숨을 죽이고 있던, 한국언론식으로 부르자면 이른바 "원로"라고 부를 만한 사람들이 우루루 귀도의 이런 선언에 전적으로 찬성한다는 댓글을 마구 올렸습니다. 오늘의 교훈은 "이도 저도 아니면 그냥 원래대로 놔두자." 정도 랄까요? -O-;;;
SDForum Python Meeting이라는 모임에서 PSF 멤버이자, ASF의 의장이기도 하며, 구글 직원이기도 한 Greg Stein에게 한 호기심 많은 파이썬 사용자가 인터뷰를 해서 정보를 마구 캐내어 왔습니다. (SDForum은 실리콘 밸리의 개발자들의 기술 사교모임 비슷한 것 같군요. 흐흐) 파이썬을 쓴다고 하기는 하고, 귀도를 데려가는 걸 봐서 뭔가 하는 것 같긴 한데, 구체적으로 어떻게 쓰는지는 베일에 싸여 있었던 것이 이제 명확히 드러났습니다!
글에 구체적으로 나와 있지만, 주요한 몇가지만 요약하자면,
구글은 주로 C++을 쓰기 때문에, C++ 코드를 SWIG으로 감싸서 쓰는 경우가 많고 점차 늘어나고 있다.
다른 언어간의 통신을 위해 자체적인 바이너리 기반 RPC 프로토콜이 있다.
구글 내부의 모든 파이썬 코드는 반드시 PEP-8을 따라야 하는데 인덴트는 2칸으로 하는 것이 차이가 있다.
구글의 빌드 시스템은 완전히 파이썬으로 돼 있고, 의존성 관리, 주기적 빌드 등 모든 것을 관리한다.
RPM같은 내부 패키징 시스템이 있는데 파이썬으로 된 것이다.
서버 관리와 서버간 정적 데이터 전송 등에 파이썬을 쓴다. 물론 모니터링, 리포팅, 로그/분석 등도 파이썬이다.
구글에서는 파이썬을 어울리는 적소에 사용하고 있기 때문에, 파이썬의 속도가 문제되는 경우는 거의 없다. 퍼포먼스가 필요한 경우에는 C/C++라이브러리를 SWIG으로 긁어서 사용한다.
그 외에도 구글이 MySQL을 주로 사용하고 있는 이유가 무척 흥미로운데, 상용 DBMS를 쓰던 시절에 벤더에게 새로운 기능을 추가해달라고 요청했을 때 심지어 개발자 비용을 대겠다고 해도 거절을 당한 경험을 하고서는, 그 다음부터 오픈소스로 바꿨다고 합니다. 그리고, 오픈소스가 아님에도 불구하고 자바를 쓰는 이유는 워낙 좋은 자바 프로그래머 인력이 많기 때문에 어쩔 수 없이 그러는 것 같군요. 흐흐.;;
더 재미있는 것들이 많이 내용에 나와 있으니 관심 있는 분들은 읽어보세요~
위 소스 둘을 보면 결과적으로는 아래 소스가 40% 정도 빠르게 동작합니다. 그렇지만, 왜 그런지 파악하는 것은 VM 내부 구조에 대한 연습을 무척 많이 하지 않고서는 쉽게 알기가 힘듭니다. 우선은 비슷한 라인이기 때문에 t += []는 inplace_add에서 resize가 일어나지 않을까 하고, 뒤의 것에서는 리스트가 계속 생성되지 않을까 하는 생각이 먼저 듭니다.
그런데, 이런 것을 진짜로 분석해보려면 파이썬 프로파일러로 해보면 라인단위로 나와서 그다지 큰 도움이 안 되고, C 프로파일러로 해봐도 대부분 인터프리터 루프가 먹고 있다는 것 정도만 파악이 되고.. 흐흐.. 그래서, 파이썬 VM 구조를 잘 모를 때도 쓸 수 있는 좋은 방법을 하나 소개합니다. 표준 파이썬에 dis 라는 디스컴파일러 모듈이 있는데, dis.dis 함수를 쓰면 코드/함수를 디스어셈블해 줍니다. 그래서 저 프로그램을 적당히 함수로 만들어서 디스어셈블을 해 보면 주요 부분이 이렇게..
그러면 디스어셈블 결과만 대충 봐도 앞의 소스는 LOAD_GLOBAL을 쓰고 있고 뒤의 것은 안 쓴다는 것을 알 수 있습니다. LOAD_GLOBAL은 딕셔너리 검색이 최소 1번에서 나쁜 경우 3~5번까지도 일어날 수 있는 옵코드이기 때문에, 있고 없고가 굉장한 성능 차이를 줄 수 있다는 것을 알 수 있습니다. 그리고, 두번째 것은 INPLACE_ADD 없이 그냥 BUILD_LIST해서 저장해버린 반면에, 첫번째 것은 INPLACE_ADD가 중간에 들어 있기 때문에, LOAD_GLOBAL 없이도 복잡한 것을 눈치챌 수 있습니다.
오늘의 연습문제: LOAD_GLOBAL/STORE_GLOBAL 외에 LOAD_FAST/STORE_FAST를 쓰면 위와 같은 소스가 굉장히 빨라질 가능성이 있습니다. 어떻게 하면 LOAD_FAST를 쓰도록 유도할 수 있을까요! (힌트: _GLOBAL은 딕셔너리 서치가 일어나고, _FAST는 미리 할당된 슬랏에서 인덱스로 바로 가져옵니다.)
2000년대 초반, Zope와 PSP, Webware for Python, mod_snake, PMZ 등 수많은 웹 프레임워크들이 쏟아져 나와서 경쟁적으로 독특한 방식으로 마구 내놓았습니다.
당시에는 현재의 Ruby on Rails나 Jakarta같은 것들이 압도적인 우위를 보이던 시절이 아니었습니다. 그러다보니 어정쩡하게 고만고만한 프레임워크가 너무 많이 나왔고, Zope 같이 너무 이질적이거나 현실적으로 투입하기가 쉽지가 않은 것에서 파생된 프레임워크들에 눌려서 별 진전이 없었던 것이 사실입니다.
이에 대해서, 귀도의 컬럼인 All Things Pythonic에 글이 올라왔습니다. 귀도는 평생 웹에는 관심도 없을 것 같더니, Cheetah도 한번 해 보고 하는군요 :)
Cheetah와 django의 템플릿 엔진을 보고서는 django의 우세라는 의견을 보였습니다. API가 우아하고 사용자에게 훨씬 친절하다고 하는군요.
현재 파이썬계의 가장 큰 프레임워크 양대 축인 Zope와 Twisted에 대한 의견도 끝에 붙였는데,
요즘의 프레임워크들은 똑같은 목적에 대해서 여러 개를 자기가
마음에 드는대로 섞어서 쓸 수 있다는 점을 특히 좋아한다고 합니다. TurboGears의 경우에도 템플릿으로 kids를 기본적으로 쓰지만, Cheetah를 쓸 수도 있고, 접속 계층은 특히 마음대로 선택해서 넣을 수 있다는 점에서 사용자가 자기 취향에 맞게 쓸 수 있다는 점을 좋아하는 듯 하군요. (원문의 뜻을 잘못 읽은 것을 서상현씨의 지적에 따라서 고침)
저는 파이썬 웹 프레임워크로는 Zope와 albatross, TurboGears, quixote를 해 봤는데, 다들 와 멋있다 싶긴 한데 정말로 같은 언어갖고 만든게 우쭈케 이렇게 다들 다르게 만들었나 하는 생각이 들면서, 혼란스럽다 웹 안 해야지 하는 생각만이 들었는데 흐흐. 앞으로는 서로 호환되는 여러가지 베이스 라이브러리를 기반으로 해서 다른 것들이라도 섞어 쓸 수 있는 그런 방향으로 가면 좋을 것 같네요.
대중적인 언어들이라면 요즘 누구나 FFI (Foreign Function Interface)를 갖고 있는 편입니다. C#(CLI)의 P/Invoke나 Haskell의 ffi같이, C언어 중심으로 이루어진 세상에 적응을 하려면
아무래도 꼭 필요하다고 볼 수 있겠지요~
그런 역할을 하고 있던게, 파이썬에서는 바로
ctypes인데,
그동안 많은 사용자들이 ctypes로 가려운 부분을 긁어가며
잘 쓰고 있었지만, 파이썬 소스코드만 짜서는 절대로 세그폴트가
나서는 안 된다는 귀도의 철학때문에 표준 파이썬에는 들어오지
못하고 있었습니다.
그런데, ctypes 안에 포함되어 있는 크로스플랫폼 ffi 라이브러리인
libffi가
gcc 안에서 automake를 쓰는 바람에, libffi 자체는 X11 라이선스임에도 불구하고, 빌드 스크립트들이 일부 GPL이 포함되어 있는 바람에 파이썬에 들어오게 되면 다른 파이썬 코드들이 GPL 영향을 받게 된다는 우려들이 나오면서 다들 라이선스 해석하느라 공황 상태에 들어갔습니다.
가장 큰 이슈는 automake가 생성해주는 aclocal.m4에 GPL 코드가 와장창 들어있어서, 그 부분을 어떻게든 제거를 하는 것이었습니다. 다들 automake는 결과 코드에 대해서는 라이선스 제한이 없다 있다고 싸우고 있었는데, 마틴이 그냥 빌드 도구를 우리가 따로 만들어서 쓰면 되지 않겠느냐고 해서, 그냥 설날기념으로 한번 automake를 제거하고 distutils에서 직접 빌드를 하도록 ctypes 패치를 해 봤습니다. :)
libffi가 생각보다 굉장히 간단한 라이브러리라 빌드과정이 복잡한 것은 전혀 없었고, configure 스크립트에서 보내주는 변수를 쓰기 위해서 fficonfig.py.in 이라는 템플릿을 autoconf에서 처리해주도록 해서 그걸 distutils쪽 스크립트에서 execfile해서 처리를 했습니다. 해놓고 나니 소스도 거의 1MB 줄고 좋네요~ 곧 ctypes가 들어갈 수 있기를 기원해 봅니다. -O-
어제 Zope 3.2 최종판이 릴리스 됐습니다. 그동안 Zope3이 계속 X3라는 이름을 달고 나왔었는데, 이번에 처음으로 안정 버전이라는 뜻으로 X를 떼고 그냥 Zope 3.2로 나왔습니다. 이는 곧 Zope 2보다 Zope 3을 앞으로 쭉 안정 버전으로 밀겠다는 뜻인데, 이미 Zope 4도 개발 중인 것 같군요.
Zope 3는 Zope 2의 경험을 토대로 해서 바닥부터 새로 만든 것인데다가 디자인 자체를 굉장히 수정한 탓에, Zope 2와 프러덕트가 거의 호환되지 않습니다. 따라서, Zope 2용으로 나왔던 COREBlog같은 프로그램들은 전혀 사용이 불가능하고 별도의 포팅이 필요하다고 합니다.
Zope 2는 앞으로 유지보수 수준의 릴리스만 하고, Zope 3이 쭉 유지될 것이라고 하니, 뭔가 Zope 2를 쓰던 사이트들은 마음의 준비를 해야할 때가 왔군요. ;;
으흐흐.. Io가 주류 언어들에 비해서 워낙 라이브러리가 부실하다보니 뭔가 하려고 하면 항상 꼭 몇개씩 발목잡는 부분이 있었습니다. 파이썬의 str에 해당하는 Sequence와 String같은 경우에도 대충 다 있는 것 같이 보이면서도, 꼭 뭔가 하려면 한 개씩 없고.. List나 Map도 참 답답할 때가 많고.. 그래서 그냥 파이썬 브릿지가 있으면 어떨까 생각하다가 우선 파이썬 바인딩을.. :) 한 30줄 짜니까 금방 되네요~
파이썬 메일링 리스트에 팀이 Zope 쪽에 구축한 빌드팜을 보여주면서
자동으로 파이썬 빌드/퇴행검사도 자동으로 할 수 있지 않겠느냐는
글을 올렸습니다. 그래서 빌드봇을 살펴봤는데,
Twisted기반으로 구현되어 있는 파이썬 프로그램이군요. :)
프로그램이 여러 플랫폼에서 돌아가야하는 경우에 특히 마이너 플랫폼이 많으면 하나 고쳤다고 막 엉뚱한 플랫폼에서 깨지고 그런 경우가 비일비재합니다. 그래서 구축하는 것이 FreeBSD의 PointyHat이나 도시락 같은 빌드팜이나 테스트팜들인데, 충분한 클러스터를 갖추고 있는 곳이라면야 이렇게 할 수 있겠지만, 개인적으로 별의 별 플랫폼을 다 지원하려면 돈이 이만 저만 드는 것이 아닙니다.
그래서, buildbot에서는 슬레이브가 정규화된 프로토콜로 분산될 수 있는 형태로 구축이 되었는데, 마스터만 하나 구축해 놓으면, 슬레이브는 자기 시스템에 계정을 따로 만들어줄 필요 없이 직접 보고해서 중앙에 로그나 성공 여부 같은 것을 알 수 있도록 하는 구조로 되어있습니다. 그래서, 희한한 플랫폼을 쓰는 사람들이 울분을 토로하고 싶을 때 빌드봇을 돌려주면 좋을 것 같군요.. :)
Io의 asString, asCharacter 같은 것 덕분에 앞뒤로 왔다갔다 하지 않고도 계속 쓸 수 있다는 점이 참 와닿아서, 파이썬에서는 그렇게 할 수 없을까 하다가, 전에 어떤 분이 파이썬에서 왜 베이스 타입에서는 메쏘드를 못 갈아치우냐 하시길래, "엇 안되나! (뻘쭘)" 했던 기억이 나서 좀 더 연구를 해 보았습니다. 으흐흐
파이썬의 타입 오브젝트의 플래그 중에 Py_TPFLAGS_HEAPTYPE이라는 것이 있는데 이것은 힙에 할당된 타입에만 들어가는 플래그라서, 즉, 런타임에 상속된 타입들은 이 플래그가 설정이 되지만, 컴파일할 때 스택에 할당된 타입 객체들은 이 플래그가 설정되어 있지 않아서 결국 "can't set attributes of built-in/extension type"라는 에러를 뱉어냅니다. 그런데, 파이썬은 타입 오브젝트가 비록 스택에 있긴 하지만 const가 아니기 때문에 실제로 딕셔너리도 할당을 하는 등 변조를 하고 gc로 관리까지 하고 있어서 변경한다고 문제가 생길 것은 없었습니다. 그래서 그 부분을 패치해서 실험해 보면, (Object/typeobject.c의 type_setattro함수의 첫 if 블럭을 주석처리)
과연.. 잘 되는데 왜 파이썬에서는 막아놓은 것일까!
그 이유는 메일링리스트를 한참 뒤져본 결과 귀도의 적극적인
의도로 막아놓은 것인데, 귀도의 설명에 따르면
빌트인 타입 오브젝트들은 여러 쓰레드에 걸친 것 같은
공유되는 컨텍스트에서 같이 사용되는 경우가 많기 때문에
문제를 발생시킬 소지가 높은 핵이라서 이런 걸 공식적으로
허용해 줄 수가 없다고 하네요.
뭔가 수긍이 가는 것 같기도 하면서도.. 파이썬의 다른 면들은
과연 그렇게 깨끗했나 의심이.. 흐흐흐.. -O- 하여간 약간
아쉽군요~
그동안 파이썬의 예외처리를 처음 접할 때 한번 쯤은 실수해 볼만한 게 바로 try-except 밑에 finally를 쓰는 것이었습니다. 예를 들어,
try:
pass
except:
pass
finally:
pass
이렇게 쓰면 야속하게도 에러가 나버리고 항상 이렇게
써야했습니다.
try:
try:
pass
except:
pass
finally:
pass
아이고 귀찮아라~~ 흐흐. 하여간 그동안 귀도가 finally가 except 절의 바깥에 있어야 except절에 확실히 걸린다는 것을 보여줄 수 있다고 안 된다고 하다가 올중반 쯤에 드디어 PEP-341을 승인하여서, except뒤에 항상 finally가 들어가고 except절도 finally에 걸리는 것으로 결정되었고,
드디어 어제 트렁크에 패치가 커밋되었습니다. 이제 자연스럽게
try-except-finally! ㅋㅋ; 그렇지만 try-finally-except로 쓰면
에러납니다~~
파이썬 2.5에 새로 들어온 표준 모듈로 hashlib이 있습니다. 원래는 md5와 sha 모듈이 따로 있었는데, 작년과 올해에 연달아서 md5와 sha1이 깨지면서 상위 해시를 추가하자는 요청에 지난 9월에 sha 상위 버전에 기존 해시 펑션을 합쳐서 hashlib이 추가되었습니다. 원래 모듈은 하위호환성으로 그대로 제공되고용~
그런데 굉장히 흥미로운 사건으로 어제 Rivest씨가 파이썬 개발자 메일링 리스트에 상위 해시펑션은 파이썬에 언제 넣어주냐고 물어보는 메일을 보낸 것입니다. 오오오오오!! 지난 번에 버그 보고하는 것도 보긴 했지만, 파이썬에 이렇게 관심이 많으실 줄이야! 으흐흐흐~~~ 뭔가 모르게 뿌듯하군요 으헤헤
하여간, hashlib의 사용법은 기존 다른 모듈에 있을 때와 다른 것은 그냥 모듈명이 흩어져 있던 것이 합쳐진 것 밖에 없습니다.
세상에 이보다 쉬운 XML 파서/제너레이터가 있을까 하는 생각이
들 정도로 단순한 API를 제공해 주는 프레드릭 런드의 ElementTree가 드디어 파이썬에 통합되었습니다. 그동안 프레드릭의 고집 때문에 다른 사람들이 토론하기를 꺼리고 있었는데 마침 이번 토론에서는 프레드릭이 적극적으로 참여하게 돼서 이제 드디어 파이썬 안에도 쓰기 쉬운 XML 파서가 생겼습니다. 이히히. 귀도가 간단하게 "pythonic"이라고 해 줄 정도로 파이썬의 기본 이념에 충실한 것이 아닌가 싶군요~
>>> from xml.etree import ElementTree as et
>>> x = et.parse('snisni.blog.xml')
>>> items = (i for i in x.getroot()[0] if i.tag == 'item')
>>> for item in items:
... print item.find('title').text
... item.find('link').text = 'http://openlook.org/'
...
유자차
신축 기숙사!
첫 눈
쇼핑욕구
체지방률
>>> x.write('fixed.xml')
오늘 드디어 파이썬 소스 저장고가 CVS에서 Subversion으로
바뀌었습니다. 원래 소스포지의
CVS를 쓰고 있었지만, 소스포지 안정성에도 문제가 있고
소스포지가 subversion 지원한다고 한지 벌써 수년이 지났는데도
진척이 없어서 결국은 기존에 파이썬 호스팅을
지원해주던 네덜란드의 ISP인 XS4ALL이 svn.python.org을
새로 지원해 주어서 운영이 되게 되었습니다.
PEP-347에
얘기된 대로, 여러가지 조건들 중에서 공중 익명 접근으로는
보통 많이 쓰듯이 DAV를 통해서 지원해 주고, 개발자들은
svn+ssh로 접근하게 되긴 했는데, 보통 방식하고는 좀 달라서
공동의 계정을 하나 두고 간단한 wrapper가 인증된 키를 구분해서
누가 커밋했는지를 표시하게 됩니다. 좀 독특하긴 하지만 돌아가긴
하는군요..
그래서 변환된 스토리지를 보면 변환 직후의 리비전이
r41336이군요. 그리고, 원래 소스포지 CVS에서는 개발자의
전체 이름을 메일 데몬에서 알려주고, 소스포지 로그인ID를
개발자 ID로 해서 썼었는데, 이제 subversion으로 바뀌면서
풀네임을 소문자로 표기한 것을 로그인네임 겸 풀네임으로
쓰게 되었습니다. 그래서, 마틴 같은 경우에는 martin.v.loewis
로 표기하게 되었고, 저는 hyeshik.chang 이 되었습니다.
대문자로 안 쓰니 영 거시기 하네요. 흐흐 -O-;
그동안 디렉토리가 너무 많아서 cvs up이나 diff 하려면 꽤
힘들었는데 이제 svn 덕 좀 보게되어 기쁩니다. ^_^
Abe Fettig가 몇달 전쯤에 미리 얘기한대로, Twisted에 대한 진짜 종이 책이 나왔군요. Twisted는 워낙 방대한 디자인이라 철학을 이해하는 데에만 한참 걸리는 것을 감안하자면, 책에서 풍부한 도안을 통해서 알려주는 것이 필요할텐데 늦게나마 아무데서나 볼 수 있게 책이 나와줘서 잘 됐습니다. (게다가 표지가 이렇게 멋지다니!!)
자세한 내용이나 목차 같은 것이 아직 올라온 온라인 서점이
없어서 무슨 내용이 다뤄졌는지는 잘 모르겠지만, 회사에서
Twisted를 쓸테야! 하고 혼자 주장할 때 "책도 나왔으면 이제 대세 아닌가?"라고
말할 수 있는 뭔가 지원군이 생겼다고 볼 수도 있겠습니다. 아하하;;;;;
Twisted가 아무래도 국내에서 어필할 수 있을만한 성격이 아니다보니, 번역서가 나오지는 못하겠지만 수입이 얼른 돼서 싸게 구입할 수 있었으면 좋겠네요~
으음.. lxr이 생각보다는 좀 설치가 간단했는데, 가장 난감한게
mod_perl 1.0에 의존성이 있어서, 아파치 1.3을 깔 수 밖에 없다는
것이군요. 그래서 아파치 1.3을 구석진 곳에다가 깔고서 localhost
에서만 받도록 해서 프락시로 연결했습니다. 으흐..
얼마전에 예고되었던 대로, 드디어 CPython의 컴파일러가 AST
기반으로 교체되었습니다. AST 파서는 거의 Perl6처럼 오랫동안
허풍웨어같은 척을 하고 있었지만, 올해 들어서 활발한 개발자들의
작업으로 거의 완성 단계에 이르러 드디어 메인 브랜치로 들어오게
되었습니다. :)
AST의 주요 개발자 중의 하나인 Neal의 설명에 따르면, AST를 사용하게 되면 Jython과 문법 정의 부분을 공유하기 때문에, 새로운 문법을 적용하는 경우에 전에 비해서 훨씬 간단해 진다고 합니다. 그리고, 원래 쓰던 파서/컴파일러에 비해서 구조화가 잘 되어 있기 때문에,
앞으로 최적화나 새로운 기능을 넣을 경우에 구조 때문에 고생하는
것이 많이 줄어들 것이라고 하네요.
우선은 속도상으로는 직접적인 이득은 없지만, 앞으로 뭔가 대단한 일이 일어날 것 같아서 기분이 상큼합니다. ^_^;
오늘은 yser님의 다음 질문에 대한 답변을 겸해서 CJKCodecs의 뒷이야기에 대해서 얘기할까 합니다.
파이썬 2.4 에 유니코드 코덱 추가된 것 보면서 신기해하는 중입니다. 오픈소스로 개발되면서 막상 한국인이 비교적 알려져있는 프로젝트에 정식으로 코드 추가 되는 걸 못본지라.. 그런데 저 많은 인코딩 정리하면서 별로 힘들진 않으셨는지? 간만에 저런걸 보니 머리가 지끈거리는군요.
사실 코드 쪽에 관심이 있습니다. 아는 분이랑 정보 교환해가며 이해할려고 한참 헤맸던 적도 있는데 국내엔 정말 자료 찾기가 힘들어서 정작 외국에서 다 찾아야 하더군요. 이럴 땐 정말 영어 독해 잘하는 게 절실합니다.
파이썬 2.4에 CJKCodecs가 들어간 것에 대해..
우선, 파이썬 2.4에 추가된 것에 대해서는 코덱을 따로 설치하지 않아도 돼서 좋긴 하지만, 한국인이 기여한 것으로는 서지원님의 제너레이터 익스프레션 구현이 좀 더 인상적입니다. :) 제너레이터 익스프레션은 누구나 쓰는 일반 문법이면서 파이썬의 장래에도 큰 영향을 미칠 부분이라서~ 코덱은 그냥 보조적인 역할이지용. 그리고, 그 외에도 한국인이 올린 패치는 수도 없이 많습니다~
국제화(i18n)에 대한 문서의 부족..
한국어 코드에 대한 것들은 사실 찾아보면 국내에도 자료가 제법 있습니다. 김경석 교수님 홈페이지도 있고, 카이스트에 있는 좀 오래된 자료 중에서도 몇가지 괜찮은 게 있습니다. 일본어나 중국어 정보처리에 대한 것은 국내에는 자료가 크게 많지는 않은 편인데, 사실 한국어 사용자 중에서 일본어나 중국어, 베트남어 정보처리를 프로그래밍 해야하는 개발자가 얼마나 될 지를 생각해 보면 그다지 자료가 많아야 할 필요는 없다고 생각합니다. 많은 개발자가 실제로 쓰는 자료가 풍부해야겠지요..
CJKCodecs의 전신 KoreanCodecs
여기부터는 유아저씨의 《신화창조의 비밀》 스타일로.. --;; CJKCodecs는 최초에 KoreanCodecs로 시작되었습니다. KoreanCodecs는 2001년에 지금은 OSK에 계시는 이만용이사님의 작품인데, 당시에 파이썬 유니코드 스펙이 나오고 얼마 지나지 않아서 나온 것이라서, 파이썬 안에 들어있는 charmap 코덱처럼 딕셔너리 자료형을 기반으로 순수 파이썬으로 구현되어 있었습니다. 룩업 때문에 일어나는 속도 저하를 극복하기 위해서, 별도로 KoreanCodecs 2.0을 fork해서, C로 작성된 코덱을 추가하였습니다. KoreanCodecs 2.0에서는 디코딩과 인코딩 모두 trie와 비슷한 자료구조를 사용해서 빠르면서도 메모리 소모가 적은 형태로 구현을 해서, 나중에 JapaneseCodecs의 구조에도 영향을 주었습니다.
KoreanCodecs 2.0이 처음 나온것이 2002년 2월이었고, 2002년 12월 정도까지 업데이트가 됐습니다.
CJKCodecs로 통합
2003년 초, KoreanCodecs, JapaneseCodecs 모두 활발히 메인테인은 되고 있었지만, 파이썬에 들어가기에 용량이 지나치게 크고 메모리를 많이 사용한다는 문제점이 지적되어서 많은 유럽어권 개발자들이 꺼리고 있었습니다. 그리고 파이썬에 들어가더라도 관리할 사람이 필요했는데, JapaneseCodecs를 개발하던 카지야마씨가 박사학위 논문으로 너무 바빠서 뭐 이런 저런... 으흐흐..
ChineseCodecs는 사실상 그때 전혀 관리되고 있지 않았고, 파이썬 2.3에서 새로 들어간 PEP 293 코덱 에러 콜백기능 때문에, 기본 코덱 구현조차 멀티바이트 인코딩에서는 극도로 어려워지고 코드 양이 엄청 늘었으며, 스트림 코덱은 정말 복잡한 상태가 돼 버렸습니다. (PEP 293을 쓴 사람은 독일 사람이라 별로 난이도에 대해서 고려를 안 한듯 했지만..;) 그래서 결국은 PEP-293을 지원하는 코덱 프레임워크를 만들고 그 걸 이용해서 한, 중, 일 인코딩을 모두 지원하는 방향으로 구현해 버렸습니다. 결국 2003년 6월 첫 CJKCodecs을 내놓았습니다.
CJKCodecs 성숙
CJKCodecs는 사실 한국에서는 인코딩이 지원되느냐 마느냐 정도로 아주 간단한 문제였기 때문에 큰 관심을 끌지는 못했지만, 일본에서는 인코딩 수가 장난이 아닌데다가 캐릭터셋도 수시로 업데이트가 되기 때문에 많은 관심을 끌었습니다. 초창기에 CJKCodecs의 일본어 캐릭터셋 중에 JIS X 0201-R과 JIS X 0208같은 경우 표준을 정확하게 준수해서 구현을 했지만 오히려 그렇게 한 것이 일본 사용자들의 현실적인 사용에 불편을 줘서, 실제로 일본에서 널리 쓰일 수 있는 형태로 대폭 개정하는 등 여러가지 현실화 작업을 거쳤습니다. 그리고, 일본의 최신 표준이었던 JIS X 0213:2000을 반영해서 거의 12개의 일본어 인코딩을 지원하기 시작했습니다.
파이썬으로 편입
파이썬 2.4 릴리스를 위한 피쳐 프리즈가 다가오던 2004년 초에, 드디어 표준 파이썬에 CJKCodecs를 통합하려는 작업을 시작했습니다. 마침 2003년 12월에 제가 itertools 모듈 관련 작업을 위해서 파이썬 커미터로 들어가 있었기 때문에, 관리상의 문제도 없었고 패치에 안간힘을 써서 메모리/소스 용량을 최소로 줄여서 서구권 사용자들에게 잘 보이도록 노력해서 결국은 별 수정 없이 들어가게 되었습니다. 당시에 사실 용량 부담을 줄이기 위해서 euc-tw나 iso-2022-cn같은 것을 지원하기 위해 필요한 CNS 11643을 빼버렸는데, 아직도 파이썬에서는 CNS 11643이 빠져 있어서 euc-tw를 지원하지 않고 있습니다만.. 대만 사람들이 별 관심이 없는지 한 번도 거기에 대해서 얘기를 들은 적이 없어서 그냥 빠진채로 놔두고 있습니다. 으흐흐;
편입 이후의 변화
파이썬에 편입된 이후에는 우선 일본에서 새로 나온 표준인 JIS X 0213:2003 지원과 홍콩의 새로운 표준인 HKSCS 2004를 지원했습니다. 소스코드가 캐릭터셋과 인코딩들이 다 각각 나뉘어 있어서 모듈 수가 20개 가까이 됐던 것을, 각 국가별로 캐릭터셋과 인코딩을 모두 묶어서 1개씩으로 만들어버렸습니다.
CJKCodecs 편입 과정에서의 느낌
CJKCodecs를 만들고 파이썬에 넣는 과정 중에서 느낀 점이 많았습니다. CJKCodecs를 만들었을 때 KoreanCodecs나 ChineseCodecs보다 빠지는 점 없이 완벽한 대체판이 될 수 있었음에도 불구하고, 한국과 중국 모두 CJKCodecs가 별로 반향이 없었다는 점에서, 사용자들의 관심은 아무래도 자기 언어를 쓰는 것에 보다 관심이 있는 것이라는 점을 깨닫게 되었습니다. 당연하겠지요. 저도 그런데. 이히히. 당연한 것을 개발에 한참 빠져있으면 까먹게 되더군요.. ㅡ.ㅜ
한편, CJKCodecs가 관심을 얻은 곳은 일본 사용자들 중에서 새 표준에 관심있는 사람들이나 서구권 개발자들이었습니다. 서구권 개발자들은 그 지긋지긋한 CJK 문제를 CJKCodecs 하나만을 끼워줌으로써 말끔히 해결할 수 있다는 점에 매력을 느낀 것 같고, 일본에는 특유의 문화로 독특한 것 좋아하는 사람들이 많아서.. -.-;; 그래서 그 덕분에 일본의 현실에서 쓰는 코드와 다른 표준들을 피해가는데 많은 도움을 얻을 수 있었습니다.
그리고 또 하나! 패치에 있어서 첫인상은 정말 중요하다는 점..
보통 패치를 올릴 때 대충 만들어서 올린 다음에, 계속 고쳐야지 하는 경우가 많은데, KoreanCodecs를 파이썬에 넣으려고 패치를 올렸을 때 초기에 버그가 좀 많아서 개발자들이 처음에 시도해 보다가 나중에는 다 고치고도 별 관심을 보이지 않았습니다. CJKCodecs 때는 그래서 리뷰에 리뷰를 거쳐서 깔끔하게 올렸더니 첫인상이 좋았던지 단번에 반응이 꽤 좋았던 것이.. 첫인상의 중요성을.. :-)
2004년 여름쯤에 파이썬 2.4가 릴리스되기 전에 collections 모듈에
타입이 1개 밖에 없는데 이름이 복수로 붙어서, 피보나치 힙을
넣자는 얘기가 있을 때 한 3주일 고민을 해서 피보나치 힙을 구현
했었습니다. 그런데, 피보나치 힙이 워낙 괴짜스러운 자료구조라서 복잡하고
편리한 것들을 추가하기에는 영 불편해서 결국은 그냥 중단했었습니다.
올해 초에는, 피보나치힙과 비슷한 용도에 사용할 수 있지만,
바이너리 트리의 특징을 유지하고 있기 때문에, 구현이 훨씬 쉬운
레드블랙 트리를 한번 구현을 해 볼까 생각을 했었습니다. 그런데~ 훈련소
다녀오고 나니까 머리가 안 돌아가서.. 이히히 ^_^;;
결국은 한참을 벼르던 레드블랙 트리 구현을 마침 숙제하기가
너무 귀찮기도 하고 파이썬 2.5도 곧 피쳐프리즈가 되지 않을까 해서 밀어넣어보려고 한번 집중해서 구현해 봤습니다. 기본적으로
제공되는 메쏘드는
T.insert(v): 값을 트리에 넣음
T.remove(v): 값을 트리에서 뺌
T.clear(): 트리를 비움
T.has_key(k): 키가 있는지 검사
T.values(): 값의 리스트를 리턴
T.keys(): 키의 리스트를 리턴
T.items(): (키, 값) 페어의 리스트를 리턴
T.nfirst(n): 작은 값부터 순서대로 n개를 리턴
T.nfirstitems(n): 작은 값부터 순서대로 n개를 (키, 값) 페어의 리스트로 리턴
T.nlast(n): 큰 값부터 순서대로 n개를 리턴
T.nlastitems(n): 큰 값부터 순서대로 n개를 (키, 값) 페어의 리스트로 리턴
T.popleft(v): v보다 작은 값을 모두 빼내고 리스트로 리턴
T.popleftitems(n): v보다 작은 값을 모두 빼내서 (키, 값) 페어의 리스트로 리턴
T.popright(v): v보다 큰 값을 모두 빼내고 리스트로 리턴
T.poprightitems(n): v보다 큰 값을 모두 빼내서 (키, 값) 페어의 리스트로 리턴
그 외에 __setitem__, __getitem__, __len__, __contains__ 이 지원됩니다.
아무래도 레드블랙트리나 피보나치힙류는 세션 테이블같이 정렬 순서에 따라서 빠르게 작업을 해야 하는 경우에 프리어러티 큐로 활용하는 것이 가장 대표적인 용례인데, 피보나치힙으로 구현을 한다면 순위를 뽑으려고 할 때 매번 extractmin을 해야하는 반면에, 레드블랙트리는 그냥 트리에서 돌아다니는 것으로 구할 수 있다는 것이 장점이라고 할 수 있겠습니다. (속도는 완전한 C 타입으로 구현하면 피보나치힙이 훨씬 빠르지만, 파이썬의 비교연산 특성상 파이썬 확장 모듈이 되면 별 차이가 안 납니다.)
shedskin이라는 Python->C++ 컴파일러가 등장했습니다. 9개월간 혼자 열심히 만들었다고 하는데, 인내력이 굉장하군요;; -O- 일부는 구글의 Summer of Code 지원으로 만들었다고 합니다.
shedskin은 PyPy와 Pyrex와 겹치는 부분이 많이 있는데, 독립적인
C++ 코드로 변환할 수 있는데, Pyrex나 PyPy처럼 파이썬 VM이
실행하듯 그냥 그대로 변환하는 것이 아니라, 정말 C레벨 코드로
바꿔버립니다. 즉, print 1+2를 하면 1+2를 계산해서 sys.stdout에다가 PyObject_Print를 호출해서 쓰는 것이 아니라, 그냥 printf("%d\n", 1+2);로 바꿔버립니다. 게다가 파이썬 라이브러리도 물고 들어가지 않기 때문에, 그냥 독립적인 프로그램이 돼 버립니다.
결과적으로 파이썬 라이브러리도 필요없고 속도도 빠르다는 면은 있지만, 파이썬 소스와 100% 호환이 안 된다는 것이 치명적이라고 하겠습니다. sys.stdout이 치환된 경우도 있을 수도 있고, 덧셈 연산이 오버플로우 처리나, 음수의 라운딩에 있어서 C와 파이썬이 서로 다르기 때문에.. 그리고, getattr, hasattr, obj.__dict__ 등의 동적 프로그래밍이 지원되는 부분이 전혀 지원되지 않는 단점이 있습니다.
아쉽게도 PyPy나 Pyrex와는 달리 파이썬 고유의 특징을 모두 무시하고 컴파일러를 만든 덕에 속도는 빠르게 됐지만 사실상 기존의 파이썬 코드들 대부분과 호환되지 않는 다는 점에서 쓸 데가 얼마나 있을지 잘 모르겠네요. 으음.. 하여간 나오긴 했으니 PyPy같은 곳에 포팅해서 쓸만한 코드가 좀 있었으면 좋겠습니다. :)
한국의 대안언어축제와
비슷한 성격의 일본의 축제인 LLDN 2005가 8월 27일에 있었다고 합니다. 우리도 비슷한 행사를 하고 있으니 관심을
가지고 좀 찾아보았습니다. :)
예산과 행사 조직
대안언어축제 초기에도 LLDN에 대한 얘기가 좀 있긴 했는데,
LLDN은 기존에 잘 꾸려진 커뮤니티들이 연합하여 하는 것이지만
대안언어축제는 유명무실한 커뮤니티들 사람들 몇몇이 임시로
모여서 하는 거라 좀 다른 면이 있습니다. 그리고 대안언어축제는
지원을 정부기관에서 했지만, LLDN은 O'Reilly Japan이나
여러 다른 출판사, 신문사, 소프트뱅크 같은 곳에서 지원을
하고 있습니다.
LLDN은 2003년부터 계속 이름이 바뀌어 왔는데,
2003년엔 LLSaturday로 토요일에 했고, 2004년에는
LLWeekend로 주말에 이틀간 했고, 올해는 LLDay&Night로 해서
낮과 늦은 밤까지 한 것 같습니다. 낮에는 아카데믹하게,
밤에는 축제적인 요소를 가미했다는군요. 대안언어축제도
1박을 하는 바람에 예산이 걷잡을 수 없이 엄청나게 불어난
것을 생각해 보면, 늦은 밤까지 해버리는 것도 괜찮은 것 같습니다. :)
세션 구성
LLDN의 낮 세션에는 "아카데믹"을 정말 그대로 실현하기 위해서인지
각 언어별로 1개씩 세션을 빼곡히 채워놓았습니다. awk, curl,
gauche, haskell, ml, perl, php, python, ruby, squeak 모두 10개나 되네요. 대안언어축제에 비해서 확실히 다양성이 있는게 무척 부럽습니다. 그리고, 대안언어축제에서는 언어보다는
언어 독립적인 것들을 많이 발표 세션에 배치한 반면에, LLDN은
발표 세션은 모두 각 언어별로 배정이 되어 있군요.
독특한 세션 - 낮
발표 세션을 제외하고 독특한 포맷의 세션을 보자면, LLDN의
대표적인 두가지 "체제 대결"과 "너라면 어떻게 쓰겠니?"가 있네요.
"체제 대결"에서는 RoR, Kahua, Sledge 세가지 웹 프레임워크의
전문가들이 나와서 발표를 하고서 사회자의 진행으로 열띤 토론을
하는 것 같습니다. 대안언어축제에서도 사실은 원래 이런 걸
해 보고 싶었는데, 사람이 모자라다보니 못한게 좀 아쉽네요..
그리고, "너라면 어떻게 쓰겠니?"는 각 언어의 참가자들이
하나씩 규정연기와 자유연기 중 선택 또는 둘 다 시연을 하게되는데,
관중이나 다른 참가자들이 "너라면!" 상황에서 구현한 것을
서로 비교해보는 정말 살떨리게 재미있을 것 같은 세션일 것 같습니다. :)
독특한 세션 - 밤
그리고, 축제의 자리인 Night에서는 "안돼 자랑", "데모 자랑", "선물 대회"가 있는데,
"안돼 자랑"에서는 보통 금지되어 있는 흑마법들을 이렇게도 할 수 있다!
하면서 "으아아아~ 안돼~~~" 하는 거라고 합니다. 다른 언어 유져들에게는 숨겨온것들은 자진해서 얘기하자는 거라는군요.. (설명해 주신 미쓰님 감사!) 그리고, "데모 자랑"에서는 백문이불여일견으로 자기가 자기 언어나 툴킷/프레임워크에서 자랑하고 싶은 것을 나와서 보여주고 다른 사람들이 "우와~~" 해주는 행사라고 합니다.
역시 재미있을 것 같습니다. 하아~
대안언어축제와는..
LLDN은 대안언어축제와 매우 유사한 주제를 다루고 있음에도 불구하고
매우 다른 형식과 규모, 조직성을 갖고 있다는 점에서 서로 배우거나 가르쳐줄 것이 많은 사이인 것 같네요. 대안언어축제의 코드레이스, 야외활동, 로제타카드는 정말 자랑할 만 한데요.. ^^
그리고, 아무래도 LLDN은 사람 수가 너무 많고 장소가 강의용 장소라서 페어나 실습은 크게 못해보는 것 같네요.
LLDN 홈페이지에 올라와 있는 블로그 트랙백을 보면 참가자들 수십명이 자기 블로그에 글을 쓰고 트랙백 보내는 걸 보면 참 부럽습니다. 우리도 내년엔! 우후훗.;
하나 희망적인 것은 LLDN은 참가자가 수백명인데 여성참가자가 한명도 없었다는군요.. (그래서 그런지 LLDN 홈페이지를 보면 페이지 마다 의미없는 여성 모델이 나오는 이미지 컷이 -_-;;)
(그런데, LLDN 블로그 소프트웨어가 OpenLook과 같은 coreblog라서 매우 반갑습니다. 크크 _-_)
그동안은 뜨는데 몇십분이 걸리고 그랬는데, 이제는 인내력이
별로 없는 사람도 어느 정도는 해 볼 수 있을 정도는 됐군요. :)
lucy(perky):~/cvs/pypy-dist% python pypy/bin/py.py
Loading grammar /usr/home/perky/cvs/pypy-dist/pypy/interpreter/pyparser/data/Grammar2.4
faking <type 'module'>
faking <type 'file'>
fake-wrapping interp file <open file '<stdout>', mode 'w' at 0x61a198>
fake-wrapping interp file <open file '<stderr>', mode 'w' at 0x61a210>
fake-wrapping interp file <open file '<stdin>', mode 'r' at 0x61a120>
PyPy 0.7.0 in StdObjSpace on top of Python 2.4.1 (startupttime: 5.13 secs)
>>>> import time
>>>> st=time.time();import os;print time.time()-st
faking <type 'posix.stat_result'>
faking <type 'posix.statvfs_result'>
13.3100180626
릴리스 노트에서도 밝히듯이 어디까지나 연구목적의 프로젝트이기
때문에, 너무 성능을 진지하게 받아들이면 안 되겠지만.. :)
언젠가는 더 나을지도 모를일~ 한동안 구체적으로 보지는 못했지만
이번 릴리스에서 특이한 점은. Armin이
"C로 구현된 두번째 파이썬을 소개합니다."라고 PyPy를 소개했다는 점~
자세히 보니까, LLVM(Low-Level Virtual Machine)이란 것이
새로 도입되었는데, 기존의 CPython이 VM과 런타임, 표준 라이브러리가
혼란스럽게 섞여있는 반면에, PyPy에서 LLVM을 백엔드로 선택하는
경우에는 VM만을 저수준으로 격리해서 C로 구현된 것을 돌리고,
런타임과 표준 라이브러리, 컴파일러 등은 파이썬으로 만든 것을
돌릴 생각인 것 같군요.
유럽연합의 지원을 충분히 받으면서 재미있는 프로젝트를 하고
있는 것 같아서, 무척 부럽습니다. :) 기대가 되는군요!
2달 전쯤에 블로그에 그냥 버스타고 왔다갔다 하던 꿈을 올렸던
"기민한 언어의 날"
행사가 드디어 현실이 되었습니다.
"대안언어축제"라는 이름으로
8월 20일,21일 양일간 강원도 홍천에 있는 대명비발디파크에서
열렸습니다. "뭔가 하긴 했구나!" 생각이 들어서 참 다행입니다. :)
기획/준비 단계
대안언어축제의 첫준비는 6월 23일 강남역에서 있었습니다.
당시에 관심을 보여주신 10분이 모여서 행사의 이름을 정하고,
어떤 형식의 행사가 될지, 내용은 어떤 것을 다룰지, 목적은
어떤 것인지, 행사날짜 등을 정했습니다. (놀랍게도 첫번째
모임에서 날짜가 확정이 되어버렸지요!)
그 이후로는 초기의 "통사" 그룹 분들이 다들 바쁘신데다, 리더격을
정하지 않다보니 제대로 굴러가지 않아서 몇번 만남이 띄엄띄엄
있었습니다. 그래서 결국은 7월말까지 거의 결정된 것 없이
시간이 지나가게 되었는데, 그때
자원봉사자들을 뽑기 시작하면서
자봉분들의 활발한 준비로 장소와 준비물 등이 진행되기 시작하였습니다.
그러나 장소는 여러가지 문제때문에
행사 11일 전에서야 결정이 되었고, 아무래도 이런 형식의 행사가
처음이다보니 시간이 많이 걸려서 행사 직전까지 자봉들은
거의 매일 회의를 해야 할 정도로 바쁘게 준비되었습니다.
행사 전날 선발대 활동
행사 전날인 8월 19일에 미리 가서 행사 준비를 하는 선발대A팀과
진흥원지원부분인 간식과 문구류를 사서 가는 선발대B팀이
출발했습니다. 자봉, 통사, 발표자와 진흥원에서 지원해주시는
이재경씨를 합해서 모두 12명이었습니다.
비발디파크에 도착해보니 참 바깥 경관이 좋아서, 뭔가 컨퍼런스만 하고 있기에는 아깝다는 생각이 좀 들더군요. 크.. 하여간, 얼른 준비 숙소가 있던 오크동 8층에 짐을 풀고, 준비를 시작했습니다. 불과 하루밖에 남지 않았는데 준비가 안 된 것이 많아서 여러모로 불안했는데, 작은 인덱스 카드에 작업을 나눠서 하다보니 사람이 많아서 생각보다 금방금방 끝나더군요. :)
저녁엔 본 행사장인 에메럴드룸으로 옮겨서 다음날 개회식에서 쓸
대안언어 도미노를 만들었습니다. 많은 분들이 여러개의 언어로 열심히 만드셔서, 저는 그냥 awk만 만들었습니다. 너무 짧아서 뻘쭘;; _-_
행사 첫날 13:40 - 개회식
드디어 행사 첫날이 되었고, 막판 개회식 준비로 다들 여념이 없었습니다. 역시 바쁘면 안 되는게 많아서.. 도미노는 제대로 안 굴러가는데 막 서울에서는 차가 하나도 안 막혀서 30분 일찍 도착한다고 하니 참 애가 타더군요. 므흐..
막상 주자분들은 일찍 오시는데, 네트워크 설치하는 업체에서는 팔당댐에서 차가 막혀서 3시간째 못오고 있다고 하고.. 그런데 세션이 있는 작은 방들에서는 네트워크 필요한 세션들이 다들 첫번째 세션으로 잡혀있고.. 거의 패닉 상태에 갈 무렵, 30분 정도 지체가 돼서 네트워크 업체가 드디어 도착해서 세팅을 하고 간신히 시작을 했습니다. 원래 주자분들을 도착하자마자 숙소로 안내할 예정이었지만 그마저도 비발디파크측에서 이전 체크아웃 시간이 늦어서 3시는 돼야 들어갈 수 있다고 그러고.. 행사 초기에는 일정 변경이 굉장히 심각했지만, 그래도 별 탈없이 지나갔습니다. ^^;
행사 첫날 15:00 - 첫 번째 멀티트랙 세션
제가 맡은 발표세션인 "동적 네임스페이스"는 별로 이름부터 크게 재미있어 보이지 않는 주제로, 아무래도 썰렁하지 않을까 생각하고 조마조마 세팅을 마치고 기다리고 있었습니다. 흐흐. 처음에 딱 2분이 들어오시고 한 5분동안 썰렁~해서 으하하하 웃으며 있었는데, 알고보니 일정이 쭉 밀려서 늦게 시작한다고 하더군요. 흐흐 그래서 작은 방이 꽉 차게 많은 분들이 오셔서 조금 부담이 되었습니다. ^^; 그런데, 준비를 크게 많이 못해서 그런지 참 설명이 여러모로 꼬여서 고생을 많이 했습니다. 전에도 몇번 리허설을 꼭 해야지 생각을 했는데 이번에도 리허설 안하고 그냥 했다가 낭패를 --;
다행히도 이번 축제에서는 발표 세션에서 발표의 비중을 크게 줄이고 대부분을 페어 실습으로 하는 방향으로 미리 발표자 논의에서 정해두었기 때문에 끝 30분정도를 그냥 실습으로 슬쩍.. 흐흐.. 주자분들이 생각했던 것보다 훨씬 파이썬을 많이 하고 계시고, 파이썬을 안 하는 분들도 쉽게 적응하시는 것 같아서 무척 즐거웠습니다. :)
행사 첫날 16:30 - 두 번째 멀티트랙 세션
그 다음에는 두 번째 멀티트랙 세션으로 Ajax와 Esoteric Langauge를 했습니다. 저는 퍼즐릿님이 진행하신 Esoteric쪽에
참가를 했는데, 처음으로 한글로 하는 난해한 프로그래밍 언어 "아희"로 프로그램을 하느라 아주 쏙 빠져서 한참을 "밯맣희"이런 코드를 입으로도 읽고 손으로도 치고 하면서 즐거워했습니다.
거의 20명 넘는 분들이 다같이 "아희"코드를 짜면서 으아아아~~
하고 있는 것을 옆에서 보고 있으려니 정말 재미있었습니다.;;
행사 첫날 20:00 - 코드레이스/코드챌린지/마인드스톰
저녁을 먹고 멀티트랙 놀이시간에 들어갔습니다. 코드레이스는
통사들이 해설과 진행을 맡고 4~5명으로 구성된 팀들이 계속
추가되는 요구조건을 만족시켜가며 순간 순간 점수를 받아서
최종적으로 점수를 많이 받는 팀이 이기는 게임이었습니다.
중간에 요구사항 변경을 팀들이 직접 발표할 수도 있고, 자기의
요구사항 변경을 10분안에 구현하지 못하는 경우의 감점 같은
여러가지 점수 제도 때문에 참가하는 팀이 재미있게 할 수
있었습니다. 또한, 스타리그 중계처럼 앞에 3명이 앉아서
각 팀의 순간순간 전황을 해설하며 얘기를 하고 있는 것도
재미있고, 앞으로도 많이 발전할 수 있는 게임이 확실합니다. :)
그런데, 아무래도 코드레이스를 좁은 방에서 참가자들만
있는 채로 해버려서 관중이 없어서 해설해도 공중에 하는
것이다보니 별로 말을 못해서 약간 그렇더군요. 크흐.
옆 방에서는 코드 챌린지와 마인드스톰을 했다고 합니다. 가 보지는 않아서 잘 모르겠지만.. ^^; 코드 챌린지는 여러 정보경시대회 스타일의 문제를 힌트로 해서 숨은 URL 찾기를 하는 놀이인데, 나중에 참가자들의 말을 전해 들으니, 재미있게 진행된 것 같았습니다. :) 상품도 좋고~ 마인드스톰에서는 원래 뭔가 만들기를 하려고 했는데, 자봉/통사 중에서도 아무도 마인드스톰을 해 본 사람도 없는데다가, CD를 빼먹고 오는 바람에 결국은 레고놀이로 했다고 합니다 흐흐;;
행사 첫날 22:00 - 양과 치타또는 늑대 놀이
밤 시간에 원래 하려고 했던 장기자랑이 아무래도 분위기를 식힐 것 같다는 판단에, 대신 치타와 양 (몇몇 팀은 늑대와 양) 놀이를 했습니다. "땀 안 흘리는 야외 놀이"를 할 예정입니다. 라는 말에 주자분들은 얼떨결에 밤에 밖에 맨손으로 나가셔서 어리둥절했지만, 규칙을 설명해 드리고 게임을 하고 있으니 막 재미있다고 계속 하자는 분도 계시고.. :) 프로그래머들 아니면 누가 이런 게임을 할까 싶지만 프로그래머들에게는 정말 재미있는 게임이었습니다!
행사 첫날 23:15 - OST (Open Space Technology)
첫날의 마지막으로 OST 시간을 가졌습니다. OST는 1200명까지 토론을 할 수 있는 집단 토론 기술로, 벌과 꽃의 메카니즘 같은 재미있는 것을 수용한 재미있는 방법이라고 합니다. :) 우선 발제자들 몇 명이 나와서 어느 자리에서 뭘 토론합니다. 하고 화이트보드에 적고 가면, 사람들이 자기가 토론하고 싶은 곳으로 가서 토론을 하다가 아무때나 다른 곳에 가고 싶을 때 여기저기 왔다갔다 하면서 토론을 하는데, 중간에도 계속 화이트보드에 새로운 주제를 낼 수 있기 때문에, 짧은 시간 안에 많은 사람들이 다양한 주제로 토론을 할 수 있습니다. 결국은 프로그래밍 언어와 기호학 , 대안언어 회사에서 쓸 수 있나 같은 주제 외에도 커피에 대한 모든 것, 한국 개발자들의 노동 조건 같은 주제까지도 재미있게 이뤄졌습니다. :)
행사 두째날 10:30 - 세번째 멀티트랙 세션
두째날 아침에는 세번째 멀티트랙 세션으로 김창준님의 EDSL, 승범이의 Squeak이 있었습니다. 저는 DSL(Domain Specific Langauge)가 적용이 가능한 부분에 요새 관심이 많은 터라 EDSL에 참가하였는데, Squeak도 옆에서 들려오는 승범이의 낭랑한 목소리에 아아 아쉽다 아쉽다 하면서 있었습니다. :)
EDSL 세션에서는 기존 언어 문법을 거의 그대로 활용하면서도 DSL의 장점을 그대로 쓸 수 있는 방법을 배웠습니다. 실습시간에는 저는 C 선행처리자를 이용한 EDSL을 해 봤는데, CJKCodecs의 ISO2022 코덱이나 multibytecodec 구현에서도 C 선행처리자로 이것저것 지저분하게 많이 해 뒀는데, EDSL 개념을 알고 구현했으면 좀 더 보기 좋은 코드가 나왔을 것 같은 생각이 들더군요~
행사 두째날 12:00 - 폐회식
폐회식도 뭔가 대안적인 방법을 찾아보다가, 자봉단이 장시간 보리차를 마시면서 토의한 결과, 회고를 전지를 놓고 마음껏 그리고 쓰는 것으로 했습니다.
우선 테이블에 앉은 사람들이 글자로 좋았던 점과 개선되었으면 하는 점을 쓴 다음에, 다른 전지를 하나 받아서 크레파스로 말을 전혀 하지 않고 문자도 안 쓰고 그림만 가지고, 느꼈던 점과 다음 행사에 바라는 점 같은 것을 쓰는 것으로 했습니다. 그런데, 그림이 아주 기상천외한 것이 많아서, 다른 테이블 사람은 커녕 옆사람이 봐도 못알아보는 것이 많아서.. 무지 재미있었습니다. 크흐~
행사 두째날 12:30 - 점심식사, 기념촬영
토요일 점심부터 일요일 점심까지 모두 4끼를 먹은 곳은 메이플동 지하의 오리엔탈 익스프레스라는 곳이었습니다. 여기가 제법 비싸기는 하지만, 보통 게를 안 넣는 음식에다가 게를 계속 넣어줘서 인상이 깊었습니다. -ㅇ-; 마지막 점심에는 장어덮밥! 꺅~~;
되돌아보며
이번 행사는 국내에서는 전례가 없던 실험적인 포맷으로 가득 채운 행사이니 만큼 성공할 수 있을지에 대해서 무척 기대가 많았습니다. 특히, 계속 일정이 지연되면서 정작 추진은 안 하면서도 조바심나고 그랬었는데, 여러 자봉분들과 김창준님, 승범군의 헌신적인 준비로 얼마되지 않은 시간동안 큰 일을 이뤄낸 것 같아서 무척 기쁩니다.
코드레이스, 치타와 양 같이 이번에 특히 재미있었던 새로운 형식들은 앞으로 좀 더 재미있게 할 수 있을 것 같다는 확신이 들었고, 일반 세션들도 페어 실습의 비율을 계속 높이는 것으로 하품나는 지루한 발표에서 탈출할 수 있다는 것도 느꼈습니다.
로제타 카드를 이용한 활동이라던지 사람들끼리의 활동을 촉진하는 활동이 뒤에 나오기 시작해서, 앞에서 활발하게 활동하기가 힘든 분위기 였다는 점은 다음에 개선하면 좀 더 흥분되는 행사가 될 것 같습니다.
이번 축제 준비로 정말 수많은 시간과 노력을 한 통사, 자봉 여러분 정말 진심으로 감사하고 있습니다. 그리고, 주자 여러분들도 지금까지 가 본 어떤 행사보다도 열린 마음으로 능동적으로 참여해 주셔서 준비가 미흡했음에도 불구하고 축제가 성공할 수 있었던 점 한동안 잊지 못할 것 같습니다. :)
또한 참가비만으로는 도저히 꾸릴 수 없는 행사였기에, 재정적으로 대부분을 지원해 주셨던 한국소프트웨어진흥원과 진행에 많은 도움을 주신 이재경씨께도 참 고맙게 생각합니다. 다음에도 많은 지원 부탁드립니다.;; _-_
예전에 PEP-340을 소개하는 글에서 약간 소개를 했던, 제너레이터 향상점들이 PEP-340이 빠진 이후에 PEP-342에 제너레이터 관련된 부분만 빠져나와서 들어오게 되었습니다. 수개월동안의 토론 끝에 방금 Phillip J. Eby씨가 구현한 것을 CVS에 넣어서 이제 큰 이변이 없는 한은, 파이썬 2.5의 가장 큰 변동사항으로 나가게 될 것 같네요.
PEP-342에서는 PEP-340에서처럼 우선 가장 큰 변경이 yield 키워드가 원래 statement였던 것이, expression으로 바뀌었다는 것입니다. 즉, 원래는 x = yield 0 이런 식의 표현이 금지되어 있다가, 이번부터는 아예 x = (yield 0) + (yield 1) 이런 것도 허용되게 되는 것! 그러니까.. 코루틴을 구현할 때 필수적이라고 할 수 있는 외부에서 중간에 인자를 던져주는 것이 가능하도록 되었습니다.
그래서 실제로 활용하는 방법을 보면,
>>> def accum():
... sum = 0
... while True:
... sum += yield sum
...
>>> a = accum(); a.next()
>>> a.send(7)
7
>>> a.send(9)
16
>>> a.throw(KeyError, 5)
Traceback (most recent call last):
File "", line 1, in ?
KeyError: 5
여기서 새로 생긴 것이 바로 제너레이터의 send 메쏘드와 throw 메쏘드인데, send는 next에 인자를 추가한 것이라고 볼 수 있고, throw는 제너레이터가 멈춰있는 부분에서 예외를 발생시키는 역할을 합니다. 즉, 이제 Twisted의 deferred처리자를 완전히 제너레이터만 갖고도 깔끔하게 구현할 수 있게 되었습니다.! 꺅 만세
그 외에는, 제너레이터에 새로이 __del__이 생겨나고, cleanup이 지원되면서 try: finally: 안에다가 yield를 쓸 수 있게 되었습니다. 제너레이터가 중간에 그냥 멈춰버린 채로 해제됐을 때 자원 해제가 불가능했던 문제가 이것으로 해결됩니다.
일단은 많은 사람들이 오랫동안 토론해서 넣은 기능인 만큼, 잘 되었으면 좋겠는데, 개인적으로는 Twisted deferred가 이제 정말로 간단하게 제너레이터로 쓸 수 있게 되었다는 점이 가장 마음에 듭니다. :)
소스포지에서 가장 오래된 CVS를 갖고 있는 프로젝트 중의 하나인 파이썬이 이제 소스포지에서 독립해서 독자적인 subversion 저장고를 가지는 쪽으로 논의가 되고 있습니다.
한 1~2년전만 해도, subversion으로 바꾸자는 얘기가 나와도 몇몇만 좋아라~ 하고 다른 사람은 시큰둥한 편이었는데, 소스포지 CVS가 서비스가 계속 안 좋아지는 데다가, subversion의 fsfs 도입이나 안정화, 그리고 소스포지가 벌써 몇년째 subversion 지원한다고 하기만 하고 소식이 없는 것에 실망한 나머지 이제 대부분이 찬성하고 있습니다.
Martin의 PEP에서 설명이 되었듯이, 이번 이동에서는 접속하는 방법을 WebDAV on HTTPS basic authentication만 허용할 예정이라고 합니다. svn+ssh는 모든 개발자에게 실 계정을 줘야하는 문제가 있고, HTTPS client certificate는 CA관리를 해야하는 문제점 때문에 여러모로 귀찮다고 합니다. 흐흐;;
하여간, 이번에 파이썬이 svn으로 옮기게 되면 맨날 파이썬 고쳐놓고 diff할 때 마다 맥용 파일들이 우구장창 우루루 올라가는 것을 안 봐도 되게 되어서 참 기쁩니다 ㅡㅇ- 이제 FreeBSD도 얼른 cvsup에 subversion fsfs 지원이 들어가서 subversion으로 옮겨버리면 참 좋을텐데~
최고의 오픈소스 GUI IDE라고 누구나 인정할 수 있는 Eclipse를 처음 보고서는 파이썬에서도 swt를 쓰면 참 좋겠다는 생각을 했었는데, 생각지도 않은 것이 이뤄져버렸군요.
GCJ를 파이썬 확장에 도입한 거의 최초의 실용 바인딩인 PyLucene이 나온 뒤에, 사실 많은 사람들이 이런 저런 유명 자바 라이브러리에 대한 바인딩을 만들어보고자 했지만, swig도 지원되지 않고 그렇다고 온통 인터페이스와 클래스가 넘쳐나는 자바 라이브러리를 일일이 클래스 하나하나 다 바인딩 만들기도 엄청난 삽질이고 해서 실제로 많은 바인딩이 나오지는 못했습니다. 그래서, PySWT에서는 저자가 여러 시행착오끝에 PyQT에서 사용하는 C++용 파이썬 확장 모듈 제너레이터인 SIP를 고쳐서 자바 클래스로 파이썬 바인딩을 만드는 것을 만들어버렸다고 합니다. 으흐흐 -ㅇ-
일단은 swt 자체가 워낙 방대한 라이브러리이니 과연 이걸 이런 식으로 해도 별 무리가 없을지는 몇가지 시도가 더 있어봐야겠지만, 큰 자바 라이브러리들도 이제 쉽게 파이썬 모듈이 나올 수 있게 됐다는 점에서 큰 의미가 있을 듯합니다. 그리고, PyQt, PyGTK, wxPython등 크로스 플랫폼을 지원하는 파이썬 툴킷들이 모두 PSF 라이선스와 호환되지 않는다는 점에서 딱히 쓸 만한 것이 없었는데, 용량은 엄청 크지만서도 라이선스면에서나 완성도 면에서나 쓸만한 툴킷이 나왔다는 점에서는 반갑네요. :)
이제 distutils에 GCJ지원이 들어가는 것과, pyrex와 swig에 자바소스 긁기 지원이 들어갈 차례인건가요? :)
일본에서 여러 해 이어오고 있는 LightWeight Languages Weekend를 보면서, 우리나라도 따로따로 하면 썰렁한 언어들을 묶어서 뭔가 시너지가 날 수 있는 것 해 보면 좋겠다! 하고 생각해 오고 있었습니다. 요새 다른 분들도 가끔 그런 것 있으면 좋겠다 말씀도 하시고, 한국소프트웨어진흥원에서도 일정 수준 지원이 가능하다고 의견을 주셔서 슬슬 준비해볼까 하고 버스에서 곰곰히 생각해 보고 있습니다. :)
아무래도, 한국에서는 PHP의 시장 점유가 엄청나게 높은 편이니, LightWeight 언어라고 하더라도 PHP는 규모가 맞지 않아 포함하지 않는 것이 좋을 것같고, 멋진 친구 승범군이 운영하는 Squeak모임도 생각나고 해서, LightWeight보다는 기민한 언어(Agile Language)로 하면 어떨까 하고 생각이 났습니다. 흐흐 그래서, 대략 Python, Perl6/Parrot, Ruby가 기간이 되고, Squeak이나 Lua, Groovy 같은 약간 다른 성격의 언어들도 가능하다면 포함이 될 수 있으면 좋을 것 같습니다.
일단, 여러 언어가 모여서 행사를 하는 것이 시너지를 내기 위해서는, 일부 언어는 알고 있지만, 아직 자세히는 모르는 다른 언어들의 특징을 느껴볼 수 있도록 주제가 너무 특정 기술에 치우치거나 기초 문법에 치중한 것은 안 될것 같다는 생각이 듭니다. 그리고, 서로의 의견을 자유롭게 교환할 수 있도록 분야별 BoF 세션 (예를 들면, TwistedWeb/Nevow와 Ruby on Rails등을 주제로한 WWW BoF나, 각 언어 간의 메타클래스 특성을 활용 아이디어들을 교환하는 세션같은..)도 공식적으로 시간을 잡거나 PyCon에서 하는 것처럼 아무데나 복도에 퍼질러 앉아서 시간 가는 줄 모르고 토론하는 것도 좋을 것 같구요. :)
파이썬마을의 순식간에 뚝딱하는 세미나들하고는 좀 다르게 미리 스티어링 그룹도 구성을 하고, 각 세션들에 대해서는 Call for Paper를 통해 공개적으로 발표하실 분을 모집해서 알차게 꾸몄으면 하는 생각이 있습니다. 아직은 그냥 저 혼자 출퇴근길에 버스에서 생각하는 아이디어에 불과한데, 앞으로 다른 여러분들께 연락을 드려서 진행을 해봐야겠습니다~
구글이 Summer of Code의 개최를 공식 발표하였습니다. PSF에서 내부적으로 얘기는 지난 주부터 있었는데, 대체로 다들 반기는 분위기 속에 잘 되어서, PSF가 지원 기관의 제일 첫번째로 올라갔군요. ^_^ (1주일동안 다른 데 소문 안 내느라 입이 어찌나 근질근질했는지 =3)
Summer of Code에서는 여름 동안에 학생들이 오픈소스에 기여도 하고 자기 능력도 계발하고 하는 의미에서 구글에서 오픈소스 기여를 지원해 주는 행사입니다. 그동안 다른 데서 있었던 Grants와는 달리 Python, Perl, Mono, Apache, Ubuntu, GNOME 등 기존의 대형 오픈소스 프로젝트 기관들이 심사와 멘터링을 맡고, 각 학생 프로젝트당 $4500, 기관에 $500를 지원하게 됩니다. 이렇게 총 200개 정도의 프로젝트를 지원하는데, 이번 기회에 학생들은 괜히 소모적인 알바로 힘만 빼고 뻘짓하는 것을 피할 수 있고, 오픈소스 프로젝트들은 열의 있는 참가자들이 할 수 있는 여러 노력형 작업들을 성취해 낼 수 있을 것 같아서 아주 결과가 기대 됩니다.
한국에서도 많은 학생들이 참가해서, 한몫도 잡고 이름도 날리고 하면 좋겠군요. (450만원!) 크크 :)
수개월 전에 사이트를 대폭 개편했지만, 당시에 모자랐던
정신력으로 -.- 첫 페이지만 제대로 보이고 클릭을 조금만 하면
여기 저기 깨져 있었습니다. 친구의 얘기도 있고 해서 주말에
사이트의 깨진 부분을 메워서 이제 대충 눌러 봐도 돌아가는
사이트처럼 변신시켰습니다. :)
방명록 부활 - 방명록을 다시 붙이고 껍데기를 좀 덜 다른 사이트처럼 안 보이게 바꿨습니다.
위키위키 링크 수정 - 아직 위키 페이지들은 복구되지 않았지만, Trac으로 구성된 위키위키를 다시 링크해 놓았습니다. 아울러 CVSWeb 대신 Trac의 소스 브라우저로 링크해 두었습니다.
"좀 더 관심이 있어요" 페이지 채움. ^.^
라이선스 페이지 한글로 채움. (zlib/libpng 라이선스입니다.)
페이징 지원 추가 - 페이지 목록이 나오는 깔끔한 것은 아니지만, 카테고리별 보기와 전체 보기에서 다음, 이전 페이지로 가는 링크를 넣고 페이징해서 볼 수 있도록 했습니다.
페이징은 희한하게도 coreblog 프러덕트 자체에는 대충 구현이 되어 있는데, 스킨에서는 전혀 사용되지 않고 있었습니다. 그래서 스킨만 좀 고치니까 잘 되는군요. :) 혹시 필요하신 분이 있으실까봐 소스를 약간 붙여넣어 봅니다.
nocomment 처리하는 부분 근처에 추가:
<dtml-unless start>
<dtml-call "REQUEST.set('start', 0)">
</dtml-unless>
본문 끝 부분에:
<dtml-comment>이전, 다음 페이지 지원</dtml-comment>
<dtml-call "REQUEST.set('entries_total', len(rev_category_entry_items(category_id=cat_id)))">
<dtml-if "int(start) > 0">
<a href="categorylist_html?cat_id=<dtml-var cat_id>&start=<dtml-var expr="max(0, int(start) - page_items)">">이전 페이지</a>
</dtml-if>
<dtml-if "int(start) + page_items < entries_total">
<a href="categorylist_html?cat_id=<dtml-var cat_id>&start=<dtml-var expr="int(start) + page_items">">다음 페이지</a>
</dtml-if>
지난 목요일인 5월 19일 거의 1년간 하지 못했던 파이썬 마을 작은 세미나를 했습니다. 이번에는 세번째인만큼 지난 번 같은 대동 화합적인 1개 트랙로 수십명 같이 듣기 모드보다는, 오래 지속될 수 있도록 관심사와 숙련 정도에 따라 필요하신 곳에 참여하실 수 있도록 2개의 트랙을 준비해서 동시에 옆 방에서 진행하는 방식으로 바꿨습니다. 사실 100명 넘게 참여하는 세미나 같으면야 당연히 이렇게 하지만.. 겨우 10명 하면 많이 하는 곳에서 이렇게 2개로 나눈다는 것이 좀 부담스럽기는 했습니다. 쿠쿠 그런데 뭐 대충 성공! (각 트랙별로 10분 정도씩 참가해 주셨습니다.)
이번에 진행한 트랙은 2개로 1번 트랙에서는 넓고 시원하고 탁 트인 방에서 이만용이사님이 "파이썬 신식 클래스 (new-style class)"를 진행하셨고, 2번 트랙은 좁고 통풍 안 되고 더운 방에서 제가 파이썬 흑마법이라는 주제로 진행을 했습니다. 각각 1시간 30분씩 진행을 했는데, 제가 진행한 2번 트랙은 더워서 다들 파이썬에 대한 열기가 후끈후끈!! (;;;) 지난 번까지는 계속 회비를 1만원으로 했는데 매번 뒷풀이를 하고 나면 돈이 모자라서 세미나 후유증으로 재정을 고려하고 그래야했습니다. 그래서 이번에는 과감히 1만 5천원으로 회비를 올렸더니만! 뒷풀이 테이블 하나에 안주를 3개씩 시키는 호화스러운 뒷풀이를 할 수 있었습니다. 하하 다들 만족하시는 분위기라.. (비싸서 안 오신다는 분도 있었지만 ㅠ.ㅠ.)
이번 세미나에서 발표한 프리젠테이션과 소스를 올려 두었습니다. 이번에 아쉽게도 못 오신 서지원님꼐서 vnc2swf로 녹화를 하면 어떻겠냐 하셨는데, 제가 아직 사용법을 숙지를 못 해서 못했네요 --; 다음엔 꼭! :)
IRC 봇 SugarCube의 주요 플러그인 중의 하나였던 지하철 플러그인이 최근에 정보 싸이트로 쓰고 있던 WebSubway가 개편을 하는 바람에 안 돌아가게 돼 버렸습니다. 한동안 고치기 귀찮아~~~을 외치며 우어우어 거리고 있다가, 휴가 중 짬을 내어 봇에서 따로 쓸 수도 있게 그냥 일반화 클래스를 만들어버렸습니다.
요새 파이썬 개발팀의 주요 이슈는 PEP-340 Anonymous Block 입니다. 거의 다른 이슈들을 완전히 누르고 하루에도 수십통씩 관련 메일이 올라올 정도로 다들 열에 올라 있는데, 이 논의와 비슷한 얘기는 이전에도 몇번 있긴 했지만 딱히 어디로 결론이 나지는 않았었습니다. (PEP-310, PEP-325) 그러나 4월 중순에 C++ 프로그래머였던 사람이 조심스럽게 질문을 한 것에 대한 답글들에서 개발자들이 열을 내기 시작해서, 귀도가 4월 27일에 직접 PEP를 쓰기에 이릅니다.
이번 PEP-340은 현재 드래프트 상태이고, 확실히 의견이 모아진 것도 아니며, 그냥 실험적으로 논의되는 상태를 정리하는 것을 위한 안이지만, 이전의 유사 주제의 PEP들에 비해 상당히 여러 분야를 한꺼번에 통합하고 있고, 신선한 개념을 많이 제공하고 있다는 점에서 뭔가 유사한 것이 약간의 부분이라도 파이썬 2.5에 들어갈 것 같은 감이 듭니다. 으흐흐~ 파이썬 2.5에는 특히 AST가 거의 들어갈 것이 확실시되고 있으니까.. 그 김에 문법도 확 -.-,;;
PEP-340에서 소개하는 Anonymous Block은 파이썬 1.5 이후의 문법 상의 가장 획기적인 변화라고 부를 수도 있겠는데, 사실 많은 수의 개발자들이 2.4까지 계속 문법 변화가 많았으니 이제 2.5부터는 문법은 바꾸지 말자하고 암묵적인 동의를 했음에도 불구하고, 이번에 예전에 수년동안 있었던 문법 변화보다 더 많은 변화가 들어가 버리니.. 파이썬 중도보수파들도 이제 파이썬의 변화에 반감을 느낄 것 같기도 합니다. 으흐~
Anonymous Block이 해결하려는 이슈를 소개해 드리자면, PEP에서 언급된 대로 "좋은 프로그래머들은 자주 나오는 코드를 재사용 가능한 함수로 분리"를 합니다. 그런데, 함수나 클래스로 쉽게 분리가 되는 경우도 많이 있지만, 어떤 경우에는 루틴의 앞부분과 끝부분, 오류처리부분과 루틴의 중간 중간이 드문드문 반복되는 패턴으로 자꾸 나오는 경우가 있습니다. 예를 들면, 공유 자원의 접근을 위한 뮤텍스라던지, DB 접근을 위한 트랜잭션 처리 블럭, HTML의 헤더/푸터나 table 앞뒤 장식, 임시 파일의 생성 등 수많은 경우가 해당이 될 수 있겠는데요. 이런 경우에는 콜백으로 빼서 클래스를 생성하자니 배보다 배꼽이 크게 되고, 그렇다고 매번 풀어쓰기에는 반복되는 로직을 자꾸 중복하게 되는 찝찝한 경우가 생기는데, 이런 경우를 극복하기 위해서 Anonymous Block (현재 파이썬 메일링에서는 그냥 "block"이라고 부르고 있습니다.)가 제안되었습니다.
즉, "block"에 진입하는 시점, 오류또는 정상 종료로 인한 이탈 시점, 반복을 하는 시점, 중간에 루프의 인자가 약간 바뀌는 시점 같은 것들을 기존의 문법인 제너레이터를 확장한 것과 짬뽕을 해서 멋지게 만들어 보자는 것이 요점입니다. 2.3부터 지원되고 있는 제너레이터는 이미 상당히 다양한 용도에 사용할 수 있는 성공한 문법이지만, next 메쏘드에 인자를 전달할 수가 없어서, 상태 관리가 매우 힘들다는 점이나 try: finally 블럭이나 try: except 블럭을 yield와 걸쳐서 사용할 수 없어서, 자원의 정상적인 해제가 불가능하다는 점에서 아쉬움이 있었는데 이러한 문제점도 여기서 완전히 해결되었습니다.
현재 상태에서 PEP-340에서 변경하는 기본 statement 변화는 이런 것들이 있습니다.
__next__ 메쏘드 신설: 기존의 이터레이터 프로토콜에서는 __next__가 아니라 next메쏘드를 쓰고 있었는데, 이 이름이 범용으로는 아무래도 맞지가 않았기에, __next__로 새로운 메쏘드를 신설하고, __next__에 이제 인자 1개가 None이 기본값인 옵셔널 인자로 들어갑니다.
__exit__ 메쏘드 신설: 이터레이터 프로토콜에 자원 해제를 위한 메쏘드가 없어서, 그동안 lock 해제 같은 것이 매우 곤란했었는데, 그 경우를 위해서 예외 발생 여부에 상관없이 항상 호출되는 __exit__ 메쏘드를 새로 만듭니다.
next() 빌트인 함수: i.__next__()라고 맨날 쓰기에는 너무 보기가 안 좋아서, next(i)로 사용할 수 있도록 빌트인 함수가 신설됩니다.
for 루프 변경: for 루프의 정의가 변경됩니다. 아래의 인자 있는 continue나 탈출 함수 호출을 위한 정의 변경이고, 예전 사용법으로 쓰는 경우는 똑같습니다.
continue 인자 추가: continue 키워드 뒤에 이제 인자를 붙일 수 있게 되었습니다. continue 키워드 뒤에 인자를 쓰는 경우에는 바깥에서 돌고 있는 for또는 "block" 블럭의 이터레이터에게 전달됩니다. 즉, for 루프의 본문과 이터레이터가 직접 통신이 가능하게 되었습니다.
Anonymous block 추가: 아직 이름이 정해지지 않은 (아직 "block"이라고 부르고 있습니다.) 새로운 블럭 키워드가 추가됩니다. 이 키워드는 for과 유사한 목적으로 사용될 수도 있지만, 이터레이터 인자를 항상 대상으로 하고 있다는 점에서 좀 다릅니다. 자세한 설명은 아래에서..
제너레이터 예외 처리: 이제 제너레이터의 yield statement가 try: except 블럭 안에도 들어갈 수 있게 되었으며, try: finally 블럭 안에도 들어갈 수 있습니다.
yield statement 리턴값: 제너레이터의 __next__로 들어오는 인자를 받기 위해서 이제 yield statement가 들어온 값을 리턴합니다.
대충 훑어봐도 엄청난 변화임이 확실히 느껴지는데, 이게 아직 확실히 정해진 것은 아니니 허어억~ 하고 미리 놀라실 필요는 없습니다. (나중에 들어가면 그때 놀라면;; -o-) Anonymous Block을 사용하는 예제로 가장 많이 나오는 DB 트랜잭션 처리 같은 경우에는 이렇게 됩니다.
def transaction(conn):
cur = conn.cursor() # 이 부분은 제너레이터 생성시 실행
cur.execute('BEGIN WORK')
try:
yield cur # 최초 인자로 한번 넘겨 줌
exception:
cur.execute('ROLLBACK') # 블럭 안에서 예외 발생 시
else:
conn.commit() # 블럭 안에서 예외 발생 없이 종료
# 이 아래가 실제 실행 시작점
block transaction(conn) as txn:
txn.execute('SQL~ SQL~~~')
그리고, 이제 yield가 리턴값을 갖을 수 있기 때문에 유사-클로져나 유사-코루틴을 이제 쓸 수가 있게 되었습니다. 예를 들어서, 이런 코드가..
def accumulator(default=0):
sum = default
while True:
sum += yield sum # 반복하면서 인자들을 모두 더함
block accumulator(0) as sum:
# 현재 총합을 보여주고 새로 더할 값을 받음
v = input('%d >>> ' % sum)
if v >= 0:
continue v # 0 이상의 수가 들어오면 더하고 계속
else:
break
흐흐.. 결국 껍데기 부분의 루틴 분리에 획기적인 개선을 가져올 수 있는 좋은 도구가 될 수 있을 만한 것 같이 보입니다. 여전히 수많은 이슈들과 특히 키워드 이름을 무엇으로 할 것인가 등의 많은 문제들이 남아있지만, 아무래도 파이썬 2.5에 들어가면 가장 멋있을 것 같은 기능임에는 틀림이 없군요. :) 문법 변화라는 점에서는 원래 예정과는 좀 다르게 간다는 점에서는 약간 찝찝한 감이 있긴 하지만.. 뭐 이제 류창우님의 말씀 대로.. 파이썬도 C++이 가던 길을 걷고 있는 건지도.. (먼산)
용이사님이 PyCon DC2005에서 기념선물로 사다주신 뱃지. :) 파이썬 로고 치고는 상당히 멋있습니다. 흐흐 공식 로고로 써도 되겠다~ -O- 오늘 이사님께 PyCon 얘기를 무지 많이 전해 들었는데, 정말 흥미로왔던 행사임이 틀림없는 듯합니다. 아아 내년엔 저도 꼭 가서 세계의 파이썬 친구들을 모두 만나고 하하하하 웃어야겠네요~ :) 아쉬우나마 사진 구경이나...
그리고, 곧 4월말 쯤에, 작년에 좀 하다가 말은 파이썬마을 작은 세미나를 이어서 하기로 했습니다. 이번에는 참여 저변을 조금 넓히기 위해, 참가자 6~8명 정도의 주제가 다른 트랙 2개로 해서 뒷풀이는 같이 하는 방법으로 하면 좋을 것 같아서, 아무래도 그렇게 할 것 같네요~ :) 주제로는 요새 모르면 남의 소스보기가 힘들어진 메타클래스 프로그래밍과 입문자용 트랙으로 py2exe, win32all를 해 보면 어떨까 생각하고 있습니다~ 자세한 것은 곧 파이썬마을에.. ^^;
파이썬 마을 질문과 답변을 보다가 갑자기 특별한 점이 하나 생각났습니다.. (몇년을 보다가 _-_)
다른 언어 질문과 답변에는 대체로, 소스를 중간에 잘라서 보여주고, 이런식으로 했는데, 안되네요.. 하고 답변도 중간에 인용을 할 때 이리 자르고 저리 자르고 해서 올라가게 되는데, 파이썬 질문과 답변 관련들은 메일링리스트/포럼, 입문자/숙련자 구분을 불문하고 질문하는 사람이나, 답변하는 사람이나 항상 인터랙티브 모드에서 명령 내린 결과와, 파이썬이 돌려준 결과값을 보여주고, 원래 자기가 원했던 것은 이런 것인데.. 하고 그 화면을 보여주는 것입니다! (지금까지는 당연하게 느껴졌던 것이 갑자기!) 오우오우. C 질문 답변을 보면 "제가요 프로그램을 짰는데 갑자기 죽어요" 이런 것 나오면 참 황당하기가 한이 없는데, 파이썬 질문 답변은 아무리 개념이 없는 사람이더라도 화면 긁어서 붙이면 해결되니까... 참 질문 답변에 최적화된 언어가 아닌가 합니다. 흐흐흐. -O-
사실 뭐 파이썬만의 특징은 아니고 인터랙티브 모드가 있으면 어디서나 다 그렇겠지만 --;; doctest 같은 곳까지 응용하고 있다는 점은 파이썬 문법을 아는 사람으로써 얼마나 뿌듯한지~~ ^___^
한동안 프리뷰 릴리스를 해서 개발자들의 마음을 설레게 했던 Twisted 2.0이 드디어 정식 릴리스 되었습니다!
저는 한 2년간 twisted를 해보기는 해 봐야하는데 그 엄청난 규모에 눌려서 손댔다가 흠칫 하고 물러서는 것을 반복해오다, 작년에서야 비로소 프로젝트에 본격적으로 twisted를 쓰기 시작했습니다. (현재 사용되고 있는 곳은 KT, 삼성네트웍스 네임서버들의 제어 에이전트와 중앙 관리 데몬..) 물론 이제는 twisted가 없으면 어떻게 살 수 있을지 참 모르겠군요 이히히. 자카르타 하위 프로젝트들 하나도 부럽지 않다구~ -O-;
Twisted 2.0은 메이저 업데이트인 만큼 엄청난 변화가 있었는데, 저는 주로 이런 것들이 눈에 띄는군요.
MIT 라이선스로 변경!! 그동안 LGPL이었던 Twisted가 전체가 모두 MIT 라이선스로 바뀌어서, 이제 원하는 마음껏 꼬아서 쓸 수 있게 되었습니다!
패키지가 여러개로 분리 1.3까지만 해도 엄청난 덩치의 패키지들이 다 묶여 있어서, 쓸데없는 것 까지도 모두 들고 다녀야 했는데, 이제 Twisted에서 Twisted Web, Twisted Mail, Lore 등 거의 10개 정도의 조각들이 떨어져 나와서, Twisted 기본 패키지에는 프레임워크와 프로토콜 정도만 남게 되었습니다.
TCP 버퍼링, 리액터 callLater 성능 대폭 향상 그동안 좋은 reactor 베이스 API들을 두고도 성능을 오방 저해하고 있었던 버퍼링, 리액터 구현쪽이 많이 개선되어서 성능이 눈에 띄게 좋아졌습니다. (진짜로 반응 속도가 다름!! -- 그동안 어떻게 했으면;;;)
컴포넌트 시스템이 Zope interface로 바뀜 그동안 이상해서 별로 쓰기가 꺼려졌던 twisted.interface가 Zope의 인터페이스로 대체되었습니다. Zope 인터페이스는 아무래도 Tim, Jeremy를 비롯한 많은 파이썬 코어 해커들이 손을 대서, 유연성이나 확장성면에서는~ :)
플러그인 시스템 지원 여러가지 종류의 파이썬 애플리케이션들이 갖고 있는 공통적인 기능 중의 하나가 플러그인인데 각자가 따로 따로 구현이 되다보니 상호운용성 같은 측면에서 안 좋은 편이었는데, 이제 twisted에서 플러그인 시스템을 지원하기 시작했습니다.
ctrl-c를 누르면 pdb가 이제 디버그 모드에서 ctrl-c를 누르면 pdb가 뜬다는군요.
그 외에도 Twisted 2.0의 변경사항들은 호기심이 가는 것들이 상당히 많은데, 1.0에서 deprecated됐던 함수들을 모두 제거했다고 하니, deprecate 메쏘드들을 사용한 애플리케이션들은 각오를 조금 해야겠네요.. (아이고 큰일났네 --;)
FreeBSD 포트에서는 마침 어제 5.4 릴리스를 위해서 프리즈된 관계로 업그레이드는 2주일 후에나 가능할 듯 합니다. 으흐~ 아쉬워요 파이썬 2.4.1도 못 넣고.. ㅠ.ㅠ
내일 워싱턴DC에서 열리는 PyCon DC 2005 Member meeting 부재자 투표를 하고 왔습니다. 매년 3월 말에 열리는 PyCon이 있을 때 마다 PSF (파이썬 소프트웨어 재단)의 회의가 있는데, 여기서 재정적인 문제나, 새로운 스폰서 회원, 추천 회원 등을 결정하고 다음 한 해동안의 PSF 보드 멤버를 투표합니다. 올해부터 부재자 투표가 새로 도입되는 바람에, 별도로 위임할 사람을 지정하는 번거로움 없이 직접 할 수 있어서 다행이었습니다. :)
올해의 투표건은,
새로운 추천 회원으로 작년 많은 활동을 했던 2명을 추가하는 것
새로운 스폰서 멤버로 ActiveGrid라는 회사를 추가하는 것
작년에 투표를 안 하고 활동이 없었던 기존 회원 2명을 명예회원으로 내리는 것
보드 멤버의 수를 기존 7명에서 8명으로 늘이는 것
새로운 보드 멤버의 선출
가 올라왔습니다. 그런데, 뭐 대체로 반대할 만한 것도 딱히 없고.. 보드 멤버도 작년처럼 치열한 게 아니라, 8명 자리에 8명이 올라와서, 그냥 이름 반복해서 쓰기군요.. 흐흐.. 결국은 모두 yes에 8명 그대로.. 거수기 신세 Y.Y
용이사님은 올해에도 PyCon 가신다던데.. 아아 저도 이제 내년부터는 자유로운 신분으로 마음대로 PyCon도 갔다 오고 할 수 있겠네요. 올해 PyCon에서는 키노트가 마이크로소프트의 Jim Hugunin이고, 마지막날에 있는 구글의 Greg Stein의 연설도 정말 기대가 되는데 말이죠 으흐~ 아쉽당~ -O-
귀도가 파이썬 개발 메일링 리스트에 흥분된 어조로 메일을 보냈습니다. "Python이 졸트 어워드 2005에서 상을 받았습니다!"
졸트 어워드라면 뭔가 먼나라 얘기인 줄 알고만 있었는데, 올해엔 파이썬이 워낙 좋아서~ :) 언어 및 개발도구 분야에서 졸트상은 아니고 그 아래로 보이는 "productivity winners"에 올랐습니다. 2001년에 YorkTown 고등학교에서 만든 Introduction to Python이라는 동영상에서 여주인공 니나가 항상 Jolt라는 음료수를 들고 다녔는데.. 니나가 파이썬을 그때 열심히 공부를 안 해서 파이썬에 상이 좀 늦게 왔나봅니다. 'o';;;
같은 분야의 1위는 이클립스인데.. 응 그래 끄덕끄덕;; 이클립스 정도면 1등할 만 하군요.. 으흐~
그 외의 다른 분야의 수상들을 보니까 눈에 띄는 게, 일반 출판물 분야의 "Joel on Software"나.. 충격적인 레이아웃으로 한빛미디어를 당혹케했던 Head First 씨리즈의 "Head First Patterns"같은 것도 있고.. (아직 읽어보지는 못했는데 꼭 사봐야겠어요 +_+) 비즈니스 통합/데이터 툴 분야에서 Toad for Oracle가 올라왔군용.. 그리고 재미있는게, Change/Configuration Management부분에서 subversion이 졸트상을 받았는데, productivity winner로 perforce가 올라왔습니다. 흐흐 제가 보기엔 perforce가 솔직히 좀 낫긴 하던데.. 심사위원들 눈에는 안 그랬던 모양입니다. -.-a;;
그리고 그 밑에 Test - Defect Tracking Tools 부분에 Fog Creek의 FogBugz가 졸트상을 받았으니.. Joel은 한꺼번에 상을 두개나 받아서 정말 상상만 해도 구름 위로 올라갈 것 같군요.. :)
이제 Python은 그냥 스크립트 언어라 부르지 말고, "award-winning" 스크립트 언어라고 불러주세요! (한국어로는 뭐라고 하지;;; 수상경력의 스크립트 언어? ;;)
파이썬을 위한 FreeBSD 플랫폼 라이브러리/커널 인터페이스 바인딩인 py-freebsd을 그동안 버려두고 있었다가, 최근에 쓰겠다는 사람이 나타나서 좀 버전업을 해 볼까 해 보고 있습니다. 흐흐 (그동안은 쓰는 사람이 없어서 --;) 몇 년전까지만 해도 별로 신경을 안 썼던 퇴행 검사(regression test) 코드들을 요새는 뭔가 새로 추가하거나 변경만 하면 넣는 분위기가 되어서, 몇몇 개발자들이 인터페이스 테스트 코드를 작성하기는 해야하는데, C로 일일이 스크립팅하려니 귀찮기가 짝이 없어서 파이썬으로 작성할까 생각해보고 있다고 합니다. :)
py-freebsd는 원래 완전 쌩노가다 코드로 직접 다 작성되어 있었는데, 제공하는 함수가 30개를 넘고, 상수 200개 정도에 이제 업그레이드하면서 cd(4)나 cam(4)같은 것들을 C 확장 타입으로 만들려고 하니까 이런 중복 작업으로 점철된 노가다 작업에 회의감이 느껴져서 친도가 안 나갔었습니다. 그 뒤로 벌써 거의 3년이 지났는데, 예전에 사람들이 좋다고 칭찬하던 pyrex가 생각나서, "그래 한번 도전해 보는거야!"
우선, py-freebsd에서 가장 간단한 함수인 getosreldate(3)를 해 봤는데. 오우. 단 몇 줄에 되는군요! (다른 데서 봤지만 직접 해보니 새로운 감동이;;;;)
cdef extern int c_getosreldate "getosreldate" ()
def getosreldate():
cdef int reldate
reldate = c_getosreldate()
if reldate == -1:
raise OSErrorFromErrno()
return reldate
흐흐 물론 SWIG에 비하면 복잡한 방법이기는 하지만, 별도의 파이썬측 모듈을 만들지 않고도 섬세한 리턴값 제어나 입력값 가공이 가능하다는 점은 아주 감동적이라, 아직까지 pyrex로 안 바꾼 것이 참 후회가 되는군요 흐흐.. 그래서 py-freebsd에서 제공하고 있는 대부분의 함수들을 순조롭게 pyrex용으로 바꾸어서 거의 원래 노력형(;;) C 소스에 비해 20%정도의 양으로 줄어버렸습니다~ :)
pyrex가 실제 활용하고 있는 사람들에게서 피드백을 많이 받아서 진짜로 필요한 것에 대한 대처가 많은지 의외로 뭔가 하려고 딱 마음을 먹었을 때 막히는 게 없었는데, 꼽아보자면 이런 것들이 있었습니다.
C스타일 include가 제공된다: 사실 별 것은 아니지만.. 아무래도 FreeBSD C 라이브러리는 네임스페이스가 그냥 평면 구조이기 때문에, 모듈 안에 여러 단계를 나누기가 애매해서, 하나의 C 모듈 안에 모두 들어가는 것이 좋았는데, C 스타일 include를 제공해 줘서, 소스 길이를 적당히 유지하면서도 대형 모듈을 만들 수 있었습니다.
트릭이 매뉴얼에 언급이 돼 있다;; 예를 들면 플랫폼에 따라서 크기가 일정하지 않은 자료형으로 되어있는 정수형 매크로를 다루기 위해서, cdef extern int를 from header 블럭 안에 써버리면, 사실 타입은 신경 안 쓰기 때문에, 별 문제 없이 넘어간다는 팁 같은 것이 아예 매뉴얼에 써 있어서, pyrex에서 제공해 주는 것만으로는 해결하기가 쉽지 않은 상황들을 어렵지 않게 편법을 이용해서 빠져나갈 수 있었습니다;; py-freebsd에서도 함수로 cdef extern해놓고서는 중간에 C 헤더 파일을 하나 include 해버려서 거기서 매크로로 선언하는 트릭을 하나.. :)
사소한 난감함에 대한 배려: FreeBSD의 statfs시스템콜은 struct statfs를 사용하기도 하고, 구현해야하는 파이썬측 함수 이름도 statfs이다보니, 삼중으로 네임 스페이스가 충돌하는데, 이런 경우에 대한 대처가 되어 있었고, 음청나게 많은 enum같은 다른 부분에서도 뭔가 난감하다 싶으면 어렵지 않게 문서에서 해결책을 찾을 수가 있었습니다.
널널하고 친숙한 문법: C 문법과 파이썬 문법을 절묘하게 섞어놔서, 매뉴얼을 안 보고도 대충 이렇게 쓰면 되겠지 하고 쓰면 다 되는게 참 신기할 정도로 잘 만들어 뒀군요. :)
한편, py-freebsd의 고유 특징인 것 같기도 하지만, 다른 곳에서도 쓰일 법한 것들인데 고려가 되지 않아서 불편한 것도 제법 있었습니다.
그때 그때 다른 struct 멤버: OS 버전이 올라가면서 빠진 멤버나 버전이 올라가면서 생긴 멤버 같은 것들을 처리해 주기 위해서 C에서의 전처리자로 뽑아주는 것이 뭔가 필요한데, 이런 것을 하기 위한 방법이 딱히 없어서, setup.py에서 struct 정의를 한번 훑어서 그 결과를 pyrex에서 include하는 방식으로 일단은 해결했습니다. --;
엄청나게 많은 상수를 간단하게 정의하기: 커널 API 함수들이다 보니, 특성상 정수형 상수가 엄청나게 많은데, 이런 것도 또 OS 버전에 따라 있기도 하고 없기도 하고, 게다가 그냥 정의하기에는 상수 1개를 정의하기 위해서 3줄씩 써줘야 하기 때문에, 상수 목록을 만들기도 힘들고 관리하기도 힘든 단점이 있어서, 이것도 결국은 간단하게 함수 호출하는 형식으로 pyrex 소스에 적어두면 setup.py에서 컴파일 전에 소스를 스캔해서, 실제 헤더 파일에 있는지 확인해서 있는 것만 cdef extern을 별도의 파일에 넣어서 include하는 방법으로 해결했습니다.. 아주 찝찝하네요 흐~;;
워닝이 너무 많아~: 어차피 generate한 소스이니까 워닝이 좀 나더라도 크게 문제가 되는 것은 없지만.. 그래도 워닝이 너무 많이 나서 참 컴파일하고 있기가 불안하다는 문제는 존재합니다. --;;;;;
몇가지 사소한 난점은 있긴 했지만, 그래도 전반적으로 바꾸고 보니 유지보수도 쉬울 것 같고, 앞으로 새로운 기능을 추가하는 것도 재미있을 것 같아서 굉장히 보람이 있습니다. :) pyrex 좋아!
아침에 일찍 출근해서 즐거운 마음으로 메일을 보고 있는데
갑자기 웬 PR이 우수수 올라와서 봤더니, 파이썬 보안 권고가 발표되었으니
얼른 포트를 고치라는 것이었습니다.;
난데없는 파이썬 보안 권고라니.. 지금까지는 파이썬은 메모리가 마구
덮어 씌워지는 보안 버그도 은근 슬쩍 잘 넘어갔는데 무슨 소리~ 하고 확인을
했는데, 정말로 이제 귀도가 보안 회사에 다니더니만 보안 버그에 대한 보안
권고문을 발표하기 시작해서 이번 SimpleXMLRPCServer 보안 버그에PSF-2005-001이라는 폼나는 번호까지
할당해서 발표를 한 것이었습니다.;;
이번 보안 버그는 SimpleXMLRPCServer의 룩업 함수에서 .이 포함된 함수 이름으로
검색하는 것을 허용하다보니 함수 아래의 파이썬 내부적 속성들을 접근해서
결국 os.system에도 접근할 수 있게 되는 버그인데, 당연히 SimpleXMLRPC를
안 쓰는 프로그램은 적용되지 않습니다.
지금까지는 그런대로 보안 버그와는 관련 없는 포트만 관리해서
VuXML업데이트하는 귀찮은 일에서
어느 정도 멀리 있었는데, PR로 VuXML업데이트 하라고 해서 이제 핸드북
보고 VuXML 쓰는 방법에 대해서 공부도 하고 --; 흑흑.~ 아침에 몰래
좀 봐서 일단엔트리를 작성하기는 했습니다마는.. 포트도 같이 업데이트를
해야해서 오후는 돼야 커밋할 수 있을 것 같군용~
사실 아직portaudit을
써 본적이 한 번도 없었는데 (부끄. *^^*;;;;;)
이번에 시험하면서 써 보니까 괜찮네요...;; (보안 버그 37개를 찾아 주는;;)
SimpleXMLRPCServer 쓰는 사람이야 뭐 별로 없으니까 큰 영향은 안 미칠
것 같지만, 이제라도 파이썬 보안 권고가 체계가 잡히고 해서, 든든하군요. :)
오늘 c.l.py에 Dimitri Tcaciuc이라는 사람이 그려서 올렸습니다. 아직 파이썬 공식 마스코트로 예쁜 것이 없어서 그려 봤다더군요. 흐흐. 대체로 반응은"파이썬은 뱀이 아니라 Monty Python's Flying Circus에서 따 온 것인데 왜 자꾸 뱀을 그리냐","너무 귀여워서 파이썬이 장난감 언어(toy language)처럼 보이게 될까봐 걱정된다","반점들이 병걸린 뱀같다."이런 반응이.. 흐흐
다운로드는여기에서 하실 수 있고, FreeBSD 포트는 레포카피를 해야 하기 때문에, 재수가 좋으면 모레 정도면lang/python을 업데이트하고 2.3을 lang/python23 으로 몰아낼 수 있을 듯 합니다. (요새 레포카피 요청을 안 해봐서 레포카피가 금방 되는지는 잘 모르겠
흐흐 지금까지 뭐 지겹게 많이 들으셨겠지만 파이썬 2.4의 주요 변경점을 간단히 요약해 보자면,
빨라짐(list, tuple 등의 기본적인 것들이 최적화가 되어서 2.3에 비해 15~20%정도 기본적으로 빨라졌음.)
펑션 데코레이터 등장 (@xxx)
None이 상수로 변경
sets빌트인 타입의 등장! (엄청 좋습니다! 꺄아~)
int, long의 통합 (이제 int에서 비트 연산을 해서 넘치면 자동으로 long으로 변환)
서지원님이 구현하신 제너레이터 익스프레션 등장 sum(x for x in range(5))
역 이터레이터 등장 (reversed)
decimal 모듈 들어옴. (이제 0.3+0.3이 0.6이 아니라고 걱정할 필요가 없습니다!)
거의 3년간의 개발 기간을 거친Zope X3가 드디어 릴리스 됐습니다! 구경을 약간 해 보니, Zope X3는 인터페이스 상에서 엄청난 변화가 있어서, 관리 화면이 완전히 바뀌어서 CMF처럼 일반 화면이랑 구분이 딱히 안 되게 되었는데, 한달 전쯤에 subversion에서 받은 것은 엄청 자주 익셉션이 떴었는데.. 요즘은 괜찮을라나 모르겠군용~독특한 점은 Wiki가 아예 디폴트로 들어있어서 위키 페이지를 기본으로 쓸 수 있는데, ZWiki보다 더 간단한 녀석이라;; -O-
아직은 Zope X3를 지원하는 프러덕트들이 거의 없어서, 금방 도입하기는 좀 힘들지만, 이번에 멋지게 변신을 완료 했으니 기대가 됩니다~ +_+
대망의 파이썬 2.4 첫 베타 릴리스인 2.4b1이 한국시간으로는 오늘 자정 12시에 릴리스 되었습니다. 2.4b1 부터는 이제 베타 릴리스라서, 기능의 추가나 기존 기능의 작동 방식 변경이 없고, 버그나 외부 인터페이스를 바꾸지 않는 향상, 명백한 결함에 대해서만 수정이 가해지게 됩니다. 2.4b1은 거의 1달 반만에 나온만큼 2.4a3에서 많이 바뀌었는데요, 대충 이런 것들이 바뀌었습니다.
lukem씨가 수개월동안 패치를 업데이트해 왔던 재시작 가능 시그널 문제가 해결되었습니다.
-m 명령행 옵션을 줘서 뒤에 모듈 이름만 주면 sys.path에서 찾아서 실행하는 기능이 추가되었습니다. (논란이 많았지만 결국은 추가 됐습니다. 흐흐;)
바이트코드 옵티마이저가 터플 묶음을 단체로 상수로 취급합니다.
새로운 subprocess 모듈이 추가되었습니다. 이 모듈은 os.system이나 os.popen의 느리고 복잡한 버전인데, viewcvs에 들어있는 popen.py와 비슷하게 구현되어있지만 좀 더 포터블하고 복잡하게 되어있습니다.
re.findall re.finditer도 다른 re모듈 함수들처럼 플래그를 받을 수 있도록 바뀌었습니다.
UTF-8과 UTF-16 내장 스트림 코덱들이 이제 완전한 stateful 상태로 동작할 수 있게 되었습니다. stateful코덱이 별도로 C로 구현된 것이 들어간 것인데, 다른 것들은 여전히 안 고쳐졌기 때문에, 멀티바이트 stateful 인코딩 중에 cjkcodecs에서 지원하는 것이나 utf-8, utf-16이 아닌 것들은 여전히 stateful 디코딩이 지원되지 않습니다. (뭐가 있는지는 안 찾아봐서;;)
httplib이 IPv6를 지원합니다.
DarwinPorts를 위해 /opt/local 을 prefix로 쓰는 라이브러리들을 인식하게 되었습니다.
저는 이제 마비노기도 끊었으니까 (;;) 다시 재미있는 파이썬질로 돌아가야겠습니다. 이히 ^^
1987년에 나온 IEEE/ANSI 표준인 IEEE854 기수법 독립적 부동소수점 연산 (Radix-independent Floating-Point Arithmentic)을 구현한 decimal 모듈은 파이썬 2.4에 들어온 모듈 중에 단연 가장 많은 관심을 받고 있고 기대가 되는 모듈입니다. 웹에서 찾아 보니까 IEEE854가 생각보다 많은 곳에서 이미 지원되고 있었는데 GNU libc에서도 몇개가 검색이 되는 걸로 봐서는 GNU libc에서도 지원이 되고 있는 것 같이 보입니다. (FreeBSD에서는 아직..)
이미 수학 연산을 많이 하시는 분이면 아시겠지만 저는 처음 들었는데, IEEE854는 IEEE754의 보완한 미래형 판(이라고 하기엔 좀 나온지 오래된;)이라고 할 수 있는데, IEEE854 스펙을 모두 지원하면 IEEE754도 지원할 수 있으니 수퍼셋이라고 봐도 될 듯 합니다. IEEE854-1987 표준은 스펙이 아주 간단히 나와있는데, 주요 특징으로는 다음과 같은 것이 있습니다.
2진법, 10진법 지원
연산되면 예외를 발생시키는 Signaling NaN과 그냥 NaN으로 만들어 버리는 Quite NaN 지원
정밀도 아래의 값을 다룰 방식 (올림, 내림, 반올림, 반내림 등등)
예외 처리
트랩 핸들러
사실 IEEE754는 구체적으로 본 적이 없어서 트랩 핸들러 같은 것까지 지원이 되는지는 잘 모르겠지만, 하여간 정말 멋지긴 합니다. 흐흐 그동안 파이썬에서 0.3+0.3했는데 왜 0.6이 안 되나요 하는 질문을 하면 "아이고 그건 원래 그런거예요." 하는 뻘쭘하기가 그지 없는 그런 말로 대답을 해 줘야 했는데, (CP4E를 표방하는 언어가 2진법으로 소수쓰는 방법까지 이해를 하라는 건 --;) 하여간 IEEE854의 10진법 표기를 쓰게 되면 프로그래머나 비프로그래머 모두 쉽게 이해할 수 있는 0.3+0.3=0.6이 되는 즐거운 세상이 올 것 같군용.
파이썬에서는 IBM에서 Rexx언어를 위해 만든 범용 10진 연산 스펙을 기준으로 해서 구현이 되어있는데, 순수 파이썬으로 무려 3천라인이 넘는 구현이 되어있습니다;; 앞으로는 아무래도 파이썬 2.5나 2.6에서 set이 그랬던 것처럼 빌트인 타입으로 들어오게 될 것 같은데, 제 욕심으로는 아무래도 파이썬 3k에서는 스트링은 모두 유니코드로, 숫자형은 모두 Decimal와 int를 통합한 형태로 됐으면 하는 바람입니다. 0.3+0.3이 0.6이 되는 그 세상을 위해 --;;
>>> from decimal import *
>>> x = Decimal('0.3')
>>> x + x
Decimal("0.6")
얼마전에 AMK가 개인 블로그에 올린 파이썬 미래를 향해라는 글이 요즘 이슈로 떠오르고 있습니다.
주요 논지로는 앞으로 계속 늘어가는 여러 기반의 써드파티 파이썬 구현들 (Jython, PyPy, IronPython, Parrot 등등)과의 평화적인 공존과 CPython의 한계성을 고려하면, 앞으로 파이썬 언어 자체의 변화를 최소화하고 표준 라이브러리를 견고하게 하고 보완하는 것에 주력하자는 것입니다. 현재 파이썬 표준 라이브러리는 대충 보면 아주 많고 잘 돌아가는 것처럼 보이기는 하지만, 사실은 메인테인 안 되는 라이브러리도 산적해 있고, 숨어있는 구조적 버그도 꽤 많은 편이라 문제가 있긴 있습니다. 그리고, .NET이나 Java, Perl같은 표준 라이브러리를 위한 모듈 네임 스페이스가 없어서, 표준 모듈로 구분하는 것이 힘들다는 문제도 있고, 여러 가지를 지적하고 있군요. 흐흐 역시 혼자 느끼는 것은 아닌가 봅니다. +_+
또한, CPython은 크로스 랭기지 VM들의 유행, GIL로 인한 SMP 효율성, 써드파티 구현의 대거 등장 등등 여러 문제로 인해서 5년 안에 아무래도 버리게 되지 않을까 하는데, 저도 .NET이랑 Parrot을 보고서는 CPython은 아무래도 3~4년 넘게 가기 힘들겠다 생각을 하고 있었기는 합니다. 크로스 랭기지의 막강함은.. -o-
이 주제에 대한 토론 중에 rhettinger가 파이썬 언어 자체에서도 앞으로 변경되어야 하는 사항에 대해서 얘기를 해 주었는데, 그 중에 빌트인 타입으로 decimal이 들어가면 좋겠다고 그래서 깜짝 놀랐습니다. 흐흐
지난 7월에 있었던 OSCON에서 직선적인 파이썬 전도사인 폴 그레이엄이 "파이썬 프로그래머는 자바 프로그래머들보다 똑똑(smart)하다."라고 하는 바람에 현장에서는 박수를 치고 난리가 났지만, 뒤에서 자바 프로그래머들에게 엄청난 공격을 받은 적이 있습니다. 평소에 폴이 늘 하는 스타일의 짓이긴 했지만. 자기 홈페이지에 왜 그렇게 말했는지에 대한 해명이 올라왔군요.
주요 내용으로는, 자바 프로그래머들은 보통 밥먹고 살기 위해서 또는 학교에서 시켜서 시작하는 경우가 많다. 그러나 파이썬 프로그래머들은 파이썬만 갖고는 밥먹고 살 방법도 묘연하고, 학교에서 시키는 경우도 드물기 때문에, 사실상 파이썬 프로그래머들이 자바 프로그래머들에 비해서는 순전히 자기 만족을 위해서 파이썬을 시작한 경우가 많다. 물론, 그런 사람들도 밥먹고 살기 위한 C나 Java, C#, VB등의 언어를 이미 알고 있는 경우가 많기 때문에, 파이썬 프로그래머들은 평균적으로 자바 프로그래머들보다 똑똑하다고 볼 수 있다. 라는 논리입니다. 흐흐흐..
폴은 그래서 "Python Paradox"라고 이름을 붙인 이런 역설을 하나 소개합니다. "소프트웨어를 비교적 덜 알려진(소수의; esoteric) 언어로 개발하는 회사는 보통 더 나은 프로그래머를 고용할 수 있는 가능성이 높다. 왜냐하면 거기에 고용된 사람들은 그런 언어를 익힐 정도로 열의가 있는 사람들이기 때문이다." 전에 "설득의 심리학"에 나왔던 역설과 비슷한 말이 됩니다. "좋은 일자리를 얻으려면, 사람들이 좋은 일자리를 얻기 위해 공부하는 언어가 아닌 것을 공부하는 것이 좋다." 구글도 자바 프로그래머를 뽑으면서 파이썬도 아는 사람을 찾는다는군요.
므흐흐.. 사실은 리눅스코리아도 파이썬을 할 줄 아는 php프로그래머, C프로그래머를 줄곧 몇년간 뽑고 있는데, 국내엔 파이썬 프로그래머 자체가 워낙 적어서 으흐~;
Zope도 아니면서 Zope에 근접하는 엄청난 속도를 자랑하는 TwistedWeb을 실제로 적용한 사업용 사이트가 나타났습니다. +_+ TwistedWeb은 참 멋지긴 하지만, 100% TwistedWeb기반으로 작동하고 있는 CIA를 봤을 때 어떻게 이렇게 느릴 수가 있는가! 하고 생각을 하고 있었는데, CIA가 아무래도 하드웨어가 안 좋았나 봅니다. ;
Superleage 사이트는 바로 그 느리기로 하면 TwistedWeb 못지않게 유명한 PostgreSQL을 사용하고 있는데, 그런대로, 복잡한 DB 작업이 일어날 만한 페이지들도 무난히 나오고 있습니다. 신기하군요. 역시 잘 만들면 되나봅니다. (또는 아직 방문자가 없거나;;)
실제로 이렇게 적용한 사이트를 보고 나니, 괜히 지금 하고 있는 실패한 D모 프로젝트를 TwistedWeb으로 했으면 좋았을 거라고 생각을 해 보게 되는군요. =.= 흐흑..
Boo에 이어 또 다른 .NET 기반의 파이썬 비슷한 언어가 발표되었습니다. 얼마전 Prothon도 .NET 기반으로 옮긴다고 했다가, Guido가 눈물로 애원해서 CPython기반에 확장으로 옮기는 것으로 됐는데, 요즘 .NET 기반 언어들이 정말 많이 나오는 걸 봐서 확실히 이제 슬슬 붐이..
Boo는 파이썬을 기반으로 자기 나름대로 컴팩트한 언어를 새로 구축했는데, 보통 많은 사람들이 요청하는 for ... as나 print의 내장함수화, using: (with:) 구문 같은 걸 도입하고 있다는 점에서 신선합니다. 그런데, 이번에 새로 나온 PyCs의 경우에는 C# 흉내를 내겠다고 하고 있는데, 기본적인 문법틀은 Prothon의 것을 따오고 있습니다. 아무래도 Prothon이 .NET으로 옮기겠다고 했다가 말아서 그 영향으로 분리가 된 것 같은데, Prothon외에도 Microsoft의 C-Omega의 컨커런시 모델이나 내장 XML/SQL 지원을 참조해서 디자인하겠다고 하니, 뭔가 웹 스크립트용으로 갱장히 간편한 언어가 나올 듯 합니다. 흐흐.
점점 파이썬 관련 언어의 구현이 많아지고 있어서 앞으로 Python 3000이 나오면, CPython이 널리 쓰이는 유일한 파이썬 구현이 아니게 될지도~~
오늘 파이썬 버그 메일링 리스트를 보다가 깜짝 놀랐습니다. Submitter: rivest라고 되어있어서 으흠. Rivest도 그렇게 영 없는 성은 아니구나~ 하고 생각을 하고 있었는데. 아니.. 이름이 Ronald인 것입니다. 오호 이름까지 같은 사람이 있군! 하고.. 버그 내용을 살펴보고 있었는데.. 헛~!!! 아니 밑에 메일이 mit.edu!! 그렇다면 이게 바로 그 진짜 Rivest씨 아닌가! 아아.. 이런 사람들은 그냥 펜 잡고 신선 놀음만 하는 줄 알았더니, 파이썬 쓰다가 파이썬 버그 보고를 "직접"할 정도의 실무 열의를 갖고 있다니 정말 감동입니다. 주르륵 주르륵. 이제 앞으로 SHA1 안 쓰고 MD5만 써야겠습니다. -O-;;;
얼마전에 Python 3000에 대한 대략적인 것을 이제 슬슬 정해 보자고 토론 되었던 대로, 오늘 PEP3000이 등록되었습니다. amk와 brett이 지난 PyCon때, 얼마전 토론, 위키에서 나온 내용 등을 토대로 정리한 것인데 처음 듣는 것도 몇개 있어서 상당히 흥미롭군요. 아직 나올 날은 멀었지만 무척 세련되어 질 것 같아서 설렙니다. 주요 차이점들 (아직 그냥 예정이고 결정된 것은 아님) 중 제가 재미있다고 생각한 것들은 이렇습니다.
문자열은 이제 유니코드!: 엊그제 블로그에서 얘기했던 대로, 이제 바이트 타입을 따로 신설하고, 자바나 C#처럼 기본 문자열 타입을 유니코드로 가 버릴 듯합니다. 이로써 세련된 다국어 지원을 좀 더 완벽히 지원할 수 있을 것 같네요. ^^;
long과 int의 완전 통합: 현재는 int와 long이 따로따로 있으면서 int가 상황에 따라 long으로 업그레이드 되는 어정쩡한 통합 구조를 택하고 있는데, Python 3000에서는 int와 long이 같은 타입으로 값에 따라 내부 표현을 정하며 외부 인터페이스는 완전히 동일한 방법을 택할 듯 합니다.
정적 타입 인자의 지원: 효율적인 최적화나 입력값의 제한 등 여러가지 정적 타입인자의 장점을 선택적으로 취하기 위해서, 필요한 경우 정적 타입을 쓸 수 있도록 합니다.
모든 클래스가 new style: 현재 Exception을 비롯한 대부분의 라이브러리에서 구식 클래스를 쓰고 있는데, Python 3000에서는 완전히 모두 new style class로 바뀝니다.
이터레이터의 대거 도입: dict.keys(), dict.items(), range(), zip() 등을 비롯한 대부분의 리스트를 리턴하는 내장 타입, 내장 함수들이 이터레이터를 리턴하도록 바뀝니다.
print, exec, lambda 키워드 소멸: print 키워드가 사라지고 write(), writeln()등의 내장 함수로 대체되며, exec키워드 대신 exec함수가 생기고, lambda는 그냥 없어집니다.
백쿼트 (``) 표현 소멸: 파이썬에서 제일 Perl스러운 부호 중의 하나인 ``가 없어집니다.
내장 함수들 대거 소멸: apply, buffer, callable, compile, coerce, input, intern, map, filter, raw_input, reduce, xrange 등 현재 다른 스타일로 대체되었거나 대체되는 중인 내장 함수들이 모두 사라집니다.
이 외에도 앞으로 10배는 더 많이 충격적인 내용이 들어가야 할 것 같은데~ 모두 좋은 아이디어를 생각해 봅시다 크흐흐;
요즘 파이썬계에서는 PEP318 펑션 데코레이터가 엄청난 태풍으로 몰아치고 지금은 다 싸우다 지쳐서 수그러드는 태세지만 여전히 결론은 안 나고 문법을 새로 도입할 때마다 겪는 진통을 톡톡히 겪고 있습니다.
그 와중에 두가지 문자열 처리 이슈가 띄엄띄엄 토론되고 있는데, 바로 "Decoding incomplete unicode"와 "adding a byte sequence type to Python"입니다. 전자는 StreamReader나 StreamWriter에서 현재 표준 UTF-8, UTF-7 코덱은 완결되지 않은 상태를 제대로 처리하지 못하고 있으며, CJKCodecs의 코덱들은 대충 파일이 끝나면 시퀀스도 끝났다고 보고 처리하고 있는데 이를 프로그램측에서 명시적으로 끝이다 아니다를 결정해 주는 API를 추가하자는 Walter의 제안으로 시작되었습니다. Walter의 제안에서는 패치도 나왔지만 API가 지나치게 복잡하고 Marc-Andre가 API가 변경되는 것에 강하게 반발하고 있어서 어떻게 될 지는 모르겠지만, 아무래도 필요하기는 할 것 같네요. CJKCodecs에서도 끝인가 아닌가 판단하는게 참 모호해서, EUC-JISX0213 코덱 같은 경우에는 호출 도중에 어디에서 짤리느냐에 따라 결과가 달라지기도 하는 문제가 있습니다 -O-
그 다음에 "adding a byte sequence type to Python"은 b"xxxx"라고 쓰면 바이트 시퀀스로 처리하고 문자열처럼 쓰지 말자 뭐 이런 내용인데, Java나 C#처럼 유니코드가 나온 이후에 나온 언어들은 대체로 다 채택하고 있는 byte와 char타입의 분리에 대한 내용입니다. 현재 파이썬에서는 "xxx"라고 쓰면 이게 싱글 바이트 시퀀스이면서 문자열을 겸하는데, 원래 싱글 바이트 시퀀스의 역할을 b"xxx" 표기법으로 바꿔버리고 "xxx"는 순수한 문자열 객체로 뭐 어쩌고 저쩌고 하자는 원래 제안이 올라왔었습니다. 그런데, 대충 토론의 결론은 이렇게 되면 하위호환성 문제가 되니까, Python 3000에서 "xxx"는 유니코드 타입으로 바꿔버리고 b"xxx"를 싱글 바이트 시퀀스로 쓰자는 쪽으로 결론이 났고 귀도가 이를 확인해 줬습니다. 그리고 물론 싱글 바이트 시퀀스 타입에서는 기존에 있던 str.lower이나 str.isalpha같은 문자열에서만 있는 메쏘드들이 다 사라질 것이라고 합니다. 현재 문자열은 뭐 영어 사용자들을 위한 문자열이나 다름이 없으니 Python 3000 아주 기대가 되는군요. 냉큼 바뀌면 좋겠습니다. ㅋㅋㅋ (그러나.. 그 기존에 문자열을 바이트 시퀀스로 쓰는 대부분의 코드들은 어찌 포팅할지 -ㅇ-)
평소에 하루에 5통 내외의 낮은 소통을 갖고 있는 파이썬 개발자 메일링 리스트에 요즘 하루에 100통 정도의 엄청난 난리가 나고 있습니다. 바로, PEP318 펑션/메쏘드 데코레이터 때문인데요. 작년부터 엄청난 토론이 있었지만 별로 예쁜 문법이 안 나왔다가, 이번엔 결국 귀도와 앤써니의 합작으로 2.4a2 릴리스 이틀 전에 기습적으로 CVS에 커밋되었습니다. 보통은 커밋 되기 전에 소스포지나 개발자 메일링 리스트에서 여러 주를 토론을 하고 리뷰를 하다가 넣는데 이번엔 거의 우리나라 국회 날치기 처리하듯이.. ;;
이번에 들어간 문법은 @method 이렇게 펑션 윗줄에 연달아 쓰는 것인데, 이 외에는 리스트를 앞이나 뒤에 달아쓰는 것, | 연산자 활용하기, ^연산자 활용하기, AS 활용하기 등등 별의 별 나올 수 있는 문법은 다 나왔지만 결국은 몇명은 좋아하고 몇명은 다 싫어하는 문법들이란 것이 나오고 말았습니다. 메일이 수백개가 오간 뒤 어느정도 @method 데코레이터 문법이 어느정도 지지자들을 모으고 있는데, 이 문법은 새로운 기호를 사용해서 기존 파이썬 기반 확장 문법을 사용하던 ipython이나 Leo 등등에서 심각한 문제를 만들고 하위호환성 보장이 전혀 안 된다는 문제가 있지만 생각보다 쓰다보면 그다지 안 예쁘지는 않다는 장점이 있군요; 저도 처음엔 펄 같아보여서 아주 싫었는데 그런대로 쓰다보니 괜찮네요 흐흐; -ㅇ-;
이번 데코레이터 날치기 통과를 계기로 파이썬이 싫어졌다고 공공연히 밝히는 유명한 개발자들이 굉장히 많기는 하지만.. 아무래도 print >> fp 문법처럼 결국은 모두 다 싫어하면서도 쓰는 문법이 되지 않을까 생각해 봅니다 --;
파이썬은 소스가 수도 코드라서 아무래도 버그 추적할 때 문서보다는 소스를 찾아댕기는 일이 많습니다. 그런데, /usr/local/lib/python2.3/site-packages/twisted .. 뭐이렇게 길다랗게 나가는 디렉토리를 매번 일일이 치고 들어가는 건 참 고통스러운 일인데.. 그래서, pydoc처럼 간단히 vi를 열 수 있는 녀석을 만들어 봤습니다.
#!/bin/sh (-)
# Written by Hye-Shik Chang <perky@FreeBSD.org>
if [ ! "$1" ]; then
echo "vipy {modulename}: opens vi session for a python module."
fi
FILEPATH=`python -c 'import '$1' as x
print x.__file__' | sed -e 's,\.py[oc]$,.py,g' -e 's,/__init__\.py$,,g'`
if [ $? != 0 ]; then
exit $?
fi
if [ -r "$FILEPATH" ]; then
$EDITOR $FILEPATH
else
echo "Module $1 not found."
fi
파이썬 릴리스 엔지니어인 앤써니 백스터씨에 따르면 이번 주 목요일에 파이썬 2.4a2를 릴리스할 예정이라고 합니다. 2.4 브랜치의 첫 릴리스이자 MSI 인스톨러가 실제 사용이 가능할 지 알아보는 첫 알파 릴리스였던 2.4a1에 이어 이번 2.4a2에서는 2.4의 가장 큰 싸움터였던 318 메쏘드 데코레이터의 시험 무대가 됩니다.
메쏘드 데코레이터는 필요성에 대해서는 대체로 최소한 +0 정도는 주고 있었지만, 공감을 얻어내는 깔끔한 문법이 하나도 나오지 않은 상태에서 반발을 사는 안만 수십개가 난립하고 있었는데, 우선 2.4a2에서 귀도의 결정으로 앤써니가 자바 스타일 문법을 그대로 사용한 것을 우선 트렁크에 넣었습니다. 이렇게 됩니다.
>>> @staticmethod
... def test(self):
... pass
...
>>> test
<staticmethod object at 0x816c8d4>
지금까지 함수 끝에다가 test = staticmethod(test)했던 다른 언어에서 건너온 사람들이 거부감을 느낄 듯 한 문법상의 문제점을 해결을 해서 뭐 그럭저럭 괜찮은 것 같기는 하지만서도.. @라는 여태까지 파이썬에서 사용되지 않았던 기호를 하나 더 사용하게 된 것은 조금 거부감이 듭니다. 뒤에 as붙이는 거나 []안에다 마구 써대는 것 보다는 그래도 훨씬 나은 것 같네요;;
그리고, 2.4a2에서는 CJKCodecs 1.1이 머지돼서 HKSCS와 JIS X 0213:2004지원이 원활해졌습니다. 또한, 인터랙티브 셸에서 sys.stdin.encoding을 존중하지 않던 문제가 해결되어, 이제 u"한글" 이런 식으로 인터랙티브 셸에서도 쓸 수 있게 되었고, 일본 사람들이 shift-jis 로캘에서 몇몇 글자를 입력하면 이스케이프때문에 에러가 나는 문제가 해결됩니다.
그 외에 국제화와 관련이 없는 주요 문제들로는
그동안 임포트 중에 실패한 모듈들이 모듈 캐시에 남아서, 그 다음에 또 임포트하면 마치 에러가 안 난 것처럼 배시시 거리고 있는 현상이 이제 고쳐졌습니다.
None이 컴파일러에서 상수형으로 처리되어 더이상 None = 1 같은 처리가 불가능해졌습니다. (..)
드디어 어제 있었던 OSCON 2004의 마지막 키노트를 앞두고 2000명의 관중 앞에서 약속대로 Parrot팀의 대표인 Dan Sugalski가 Guido에게 크림 파이를 맞았습니다. 그리고 10달러와 맥주 12팩을 받았다고 합니다. 받은 맥주들은 밴쿠버 파이썬 워크샵에서 나눠먹는다는군요. ^^^;
이번에 패럿팀에서는 Leopold Toetsch가 좀 늦게 작업을 시작해서 혼자서 열심히 단기간에 많은 걸 이뤄내기는 했지만, Guido가 패럿을 X먹이기 위해 만들었다고 알려진 패럿 벤치의 b0.py를 구현하는데 결국은 시간 부족으로 실패해서, 다른 벤치마크 부분은 그런대로 속도가 나왔음에도 불구하고 진 것으로 처리가 됐습니다.
Leo의 예상으로는 구현을 다 끝내면 CPython보다 Parrot위의 파이썬이 3배는 더 빠르지 않겠느냐고 밝혔는데 글쎄요 흐흐 두고 볼 일이겠죠;; -O-; 하여간 그래도 패럿의 참패로 끝나지는 않아서 다행스럽습니다.
반면, Iron Python은 현재 b0.py도 완벽하게 통과하고 있는데, 이제 Jim Hugunin이 MS CLR 팀에 합류했다는 점에서 더욱 기대가 됩니다. (역시 편파적인 멘트를 해 본다;; )
Iron Python을 이제 받아서 대충 한번 둘러 봤습니다. 프로젝트 자체는 Visual Studio .NET 기반의 프로젝트 파일로 되어있고, mono에서 컴파일이 가능한 프로젝트 파일은 따로 없는 듯 합니다. 그렇지만 다행히도 컴파일된 바이너리가 들어있어서 빌드 걱정 없이 그냥 실행해 볼 수 있었습니다.
% mono bin/IronPythonConsole.exe
>>> [x*2 for x in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> import sys
>>> sys.platform
'java-clr'
>>> raise ValueError
IronPython.Objects.PythonValueError:
in <0x000df> IronPython.Objects.Ops:Raise (object,object,object)
in <0x00047> input_3:Run (IronPython.Objects.Frame)
in <0x001c5> IronPythonConsole.IronPython:DoInteractive ()
트레이스 백 모양이 파이썬 트레이스백이 아니라 자바 형식이라 좀 어색하군요 흐흐; 그리고 sys.platform이 웬 'java-clr' --;; 아직 os모듈은 없고, 현재 Iron Python에 들어있는 모듈은 __builtins__, imp, math, nt, re, struct, sys, time이 있습니다. 뭔가 벤치마크를 위해 time을 빼놓지는 않았다는 느낌이.. :
CPython보다 빠르다는 속도를 한번 시험해 봤습니다. 테스트 코드는 뭐 아주 간단한 파이썬 취약성 루틴의 대표적인.. while안에서 덧셈하기.. 흐흐;;
>>> def test():
... x = 0
... while x < 1000000:
... x += 1
... return x
...
결과는
Iron Python 0.6
CPython 2.3
CPython 2.4
0.972
0.625
0.595
아아. 아쉽게도(?) CPython이 간단한 루틴에서는 더 빠르군요. ;; (기분이 묘하다..)
드디어 한국어 코덱이 들어간 최초의 파이썬 릴리스인 2.4a1이 나왔습니다. 으흐흐~ 마비노기때매 CJKCodecs 1.1을 못 넣은 것이 정말 한스럽지만.. 마비노기 나빠요~
프비 포트도 앤쏘니가 파일 올리자 마자 바로 업데이트 했습니다~ 흐흐; 프비 사용자는 바로 cd /usr/ports/lang/python-devel && make install clean 하세용~
그리고, 이번 주 토요일에는 freenode에서 Python Bugday 2차가 열릴 예정입니다. 벌써부터 2.4a1 받은 사람들이 버그를 와장창 올리고 있는데, 이번에는 회사에 토요일, 일요일도 나오라고 하는 바람에 버그데이 참가를 못 할 것같아서 무척 아쉽습니다. 으흐흐. 지원님이 참가하실 것 같으니 관심 있는 분들은 같이 참여를~~
"파이썬은 C로 되어있어서 뭐든 만들 수 있어~"
"그럼 운영체제도 만들 수 있어?"
"응 그럼, 가능 할꺼야. (.... 속으로는 의심을 한다..)
"설마.. (역시나 의심 한다..)
파이썬을 광고하는 장면에서 자주 있는 장면이었습니다. 아 이제 이런 말이 그다지 비현실적인 말이 아니라는 것을 증명해 줄 만한 프로젝트가 등장했군요. 바로 Unununium 입니다.
굉장히 이상한 스펠의 이 단어는 대충 "운운우니움"정도로 읽으면 될 듯 합니다. 여기서 "ㅜ"들은 모두 moon에서의 "우~"같은 장음이기 때문에 읽는데 시간이 좀 걸립니다. 다 같이 따라해 보세요~ "운운우니움" ..;;;
이 운영체제는 기존의 운영체제들이 구현의 간편성, 엔지니어링 측면에서의 디자인을 기반으로 했기에, 사용자 측면에서의 여러 직관적이고 우아한 기능들을 제공해 주지 못하고 있는 것에 불만족을 느낀 저자가 뭐 이걸 좀 바꿔보겠다고 한 것인데, 파일시스템이 portalfs나 LUFS처럼 여러 프로토콜을 밑에 끼고 들어갈 수 있도록, 일반적인 통합을 이루고, 애플리케이션 프로세스들이 서로 완연한 상호작용으로 DCOM이나 bonobo같은 컴포넌트 이상의 상호 통합을 이룰 수 있도록 한다는군요. 그리고, OS 자체 Persistence를 지원해서 그냥 껐다 켜도 원래 OS 상태로 돌아가게 한다는데.. 뭐 대충 구현한다는 것은 어쨌거나 대체로 기존에 있는 기술이랑 비슷하긴 하네요 흐흐;;
그런데, 실제로 파이썬으로 다 하는 것은 아니고, 지금은 상당수가 어셈블리로 구현이 되어 있긴 한데, 그 위에 많은 부분을 파이썬으로 구현할 예정이라고 합니다. 그런데, 파이썬으로 구현하면 느리지 않겠느냐 하는 것에 대한 해결책은 파이썬이 느린 것은 언어 자체가 느린 것이 아니라, 구현이 느릴 뿐이니 자기가 파이썬을 빨리 해 보겠다는데.. 과연 그 네임 스페이스를 그대로 살린 채로 파이썬을 빠르게 할 수 있을 지는 의문입니다. ㅎㅎ;;;
빠른 시간 안에 큰 실적을 낼 것 같아 보이지는 않지만, 이런 ㅂㅌ 프로젝트가 하나 진행 되면 아무래도 부산물이 제법 나올 테니 그게 기대가 되는군요. ^^;;
예전에 파이썬 블로그 모음집? 뭐 비슷한 길쭉한 이름으로 제공되던 서비스가 드디어, 유행에 맞춰서 플래닛 파이썬으로 도메인을 샀군요. 엄청나게 많은 피드들이 들어가 있는데, "플래닛 파이썬 한국"도 얼른 만들어서 sanxiyn님이 혼자만 좋은 것 알고 있지 못하도록 해야겠습니다. ^^^;;;
파이썬 2.4의 첫 알파 릴리스가 곧 임박했기에, 그 후에는 크게 변화가 있는 작업을 하기가 힘들어서, 우선 급한 JIS X 0213:2004 지원과 CNS 11643 (euc-tw, iso-2022-cn) 지원을 넣고, 좀 하는 김에, 용량도 줄이고 모듈 개수도 팍팍 줄이기 위해서, 기존에 파이썬 코덱 1개당, C 코덱 1개씩으로 나뉘어 있던 구조에서, 팍 줄여서 각 국가별 1 코덱 모듈로 모두 합쳐버리는 방식으로 하려고 하고 있습니다.
원래는 한국어의 경우에 euc-kr과 cp949를 분리하고, 일본어의 경우에는 JIS X 0208, JIS X 0212로 해결되는 묶음 하나, JIS X 0213을 쓰는 묶음 하나 이렇게 또 분리를 할 계획이었는데, 엊그제의 python-dev에서의 토론에서 Marc-Andre가 아무래도 그냥 합치는게 근래의 OS에서는 훨씬 낫겠다 해서, 그냥 합치기로 했습니다. 그래서 결국은 CJKCodecs 관련 모듈로 2.4에 최종적으로 들어가는 C 모듈은 현재 24개에서 _codecs_{cn,jp,kr,tw}와 _multibytecodec 이렇게 5개로 줄어들게 되었습니다.
우선, 모듈 간에 합치는 것은 ISO-2022-JP 계열 인코딩을 제외하고는 작업이 완료되었고, ISO-2022-JP 계열 인코딩 간에, 같은 모듈로 들어가는 경우 난감한 게 좀 있어서, 그것과 JIS X 0213:2004, CNS 11643 지원을 주말에 넣어서 다음 주 초에 CJKCodecs 1.1 베타1을 릴리스하려고 하고 있습니다. 파이썬에 머지하는 것은 아무래도 테스트를 좀 하자면 월말은 되어야 될 것 같군요~
예전에 shells/perlsh 라는 걸 보고서는 참 펄 세상은 희한한 사람들이 많구나 하고 생각했는데, 이제 pysh도 나왔군요! 본셸 스크립트를 익히기 전에 셸에서 파이썬식으로 하면 참 좋겠다 하고 생각했었는데, 이제 bash 스타일로 만들었다는 pysh에서 그 꿈이 실현된 것 입니다!
우선 이건 readline 모듈을 사용하기 때문에 행 편집면에서는 bash와 차이점이 거의 없긴 한데, 아직 컴플리션은 완벽하지는 않네요. 그리고 환경변수를 쓰는 방법이 셸과도 다르고 파이썬식도 아니고 어정쩡 해서 그게 좀 어색하기도 하고.. 하여간 파이썬 명령을 셸에서 막 섞어서 쓸 수 있다는 것은 참 매력인 듯합니다.
% python pysh.py
Welcome to PySH!
[perky@miffy /usr/home/perky]$ for i in range(3): ls i
ls: 0: No such file or directory
ls: 1: No such file or directory
ls: 2: No such file or directory
POSIX에서는 wcswidth 와 wcwidth 로 지원하고 있는, 동아시아 문자 글자폭 지원을 파이썬에도 넣었습니다. 글자폭이 지원되면 터미널이나 트레이스백 같은 고정폭 환경에서 한글이 들어갔을 때 뒤로 쭉쭉 밀리는 현상을 패치할 수 있게 되고, calendar.wdayheader 같이 지금 ISO-8859권 사용자들한테만 제대로 돌아가고 있는 함수들도 앞으로 제대로 돌아가게 바꿀 수 있게 됩니다~
추가된 메소드는 unicode.width와 unicode.iswide 두 개 입니다. unicode.width는 유니코드 문자열의 폭을 정수값으로 리턴해 주고, unicode.iswide는 str.isalpha류의 메소드들 처럼 그냥 넣으면 넓은 건지 알려줍니다.
c.l.py에 답글로 막 이런 삽질을 하다니 정말 대단하다. 앞으로 유지보수가 걱정된다 글이 올라올 정도인데 흐흐. 아주 흥미롭습니다. 얼른 다른 패키징 시스템에 없는 것들을 얼른 FreeBSD에 옮겨야겠네요. devel/py-freebsd 나 devel/py-kqueue 가 빠진 것은 좀 실망입니다~ 흐흐.~ (욕심쟁이 =3 =33)
Twisted는 그동안 말로나 들어 왔지, 무지 복잡하고 어렵다고 해서 접근도 안 하고 있었는데, 요즘 Twisted의 매력이 흠뻑 빠져서 헤엄치고 삽니다. 이히히. ㄴ(:D)ㄱ へっへっへっへっ 어푸어푸~~
Twisted MSN!
Twisted안에 twisted.protocols.msn에서 MSN 프로토콜을 지원하고 있기에, 그래 SugarCube에 MSN 지원이나 넣어볼까 하는 생각에 한번 해 봤는데, 생각보다 매뉴얼이 구현 자체 위주로만 되어있고, 사용하는 것에 대해서는 문서화가 되어있지 않는 바람에 어떻게 하는지 알기가 힘들었습니다. 게다가, 유닛테스트에도 코드가 상당히 들어있는데, 이게 네트워크 프로토콜 코드를 테스트하는 것이다 보니, 전혀 실제 사용하고는 다르게, 부분 부분을 단편적으로 가짜 입력을 넣어서 처리하는거라, 실제로 어떻게 쓰는지 상상하기가 힘들었다는.. 으흐흑. 한 3시간 삽질 끝에, MSN에서 대화하는 방법을 알아냈습니다; 원래 있는 msn_example.py에는 그냥 notification까지만 접속이 되는데 switchboard까지 해서 대답하도록 해 보았습니다. 소스
Twisted 소감은?
Twisted는 아무래도 크게 할 작정을 하고 만든거라 Medusa와는 완전히 다른 방식이었습니다. 비동기 뿐만 아니라, 쓰레드 스케줄링도 어느 정도 조절이 가능하고, deferred 모델이나, factory, interface-adapter 모델 같이 소스 코드 유지 보수성을 위한 여러가지 도구들을 많이 갖고 있어서 작은 프레임웍 위에서 직접 다 만드는 방식에 비해, 디자인 상 포용력을 넓혀서 "이 산이 아닌게벼!" 하고 느껴질 때에도 다른 산으로 쉽게 옮아갈 수 있는 능력이! 그런데, 좀 아무래도 진입 장벽이 높은 편인데, 입문용 매뉴얼 "The Evolution of Finger"가 아주 잘 쓰여 있어서 입문의 문제점도 어느 정도 극복한 것 같습니다.
Python 2.3.4가 원래 지난 주에 릴리스될 예정이었지만, Thomas Heller씨가 집안 사정으로 이번 주말에 릴리스될 예정인데, 미리 따라잡기 위해서 CJKPython 2.3.4작업을 했습니다. 윈도우 쓰시는 분들은 테스트 해 보시고 이상한 것 있으면 알려주세요~
이번에 작업한 곳은
원래 인터프리터에서 u'한글'쓰면 iso8859-1로 인식해버려서 이상하게 들어가는 문제를 패치해서 넣었습니다. (이 부분은 업스트림해서 지금 Martin이 리뷰하는 중입니다.)
IDLE에서도 같은 현상이 있던 문제를 고쳤습니다. 이 부분은 idlelib.PyShell에서 runsource할 때 compile에 직접 인코딩해서 던져주기 때문에, 전혀 인코딩 정보를 알 수 없어서 iso8859-1로 인식하는데 '# coding: encoding' 을 앞에 붙여주도록 해버렸습니다. 흐흐
MSVCRT와 MSVCIRT등 라이브러리를 전혀 업데이트 안 하게 했습니다. 윈도우 98 사용자분들이 매우 불편해 하시길래~ 뭐 요즘이야 윈도우 업데이트 안 하면 큰일나는 세상이니 웬만큼은 업데이트가 됐겠죠~
서지원님이 구현하신 PEP289 Generator Expression이 드디어 CVS에 들어갔습니다. 이제 파이썬 CVS에서 체크 아웃하면 패치 안 하고도 바로 제너레이터 익스프레션을 쓸 수 있습니다! 와하하하.
이번에 들어간 것은 첫번째 루프 변수만 precompute하고 나머지는 레이지 바인딩을 하는 귀도가 제안한 스펙으로, 가장 헷갈리지만 가장 실용적이기는 한 방식입니다. 여전히 많은 사람들이 완전한 레이지 바인딩이나 완전한 얼리 바인딩을 하자고 외치고 있긴 하지만, 귀도는 그냥 2.4 알파 1까지는 이대로 가자고 합니다. -ㅇ-; 알파 1을 본 사람들이 뭔가 얘기하면 그 때가서 생각해 보자는군용~ 크흐흐
파이썬 2.3.4 RC 1이 릴리스되었습니다. 2.3.4가 정식으로 나오기 전 마지막 릴리스 후보이며, 2.3.3에서의 주요 변경사항은 대부분 버그 수정에 관한 것입니다. 제가 고친 건 전체 22개 중에 3개군요. ^^;; 정식 릴리스는 5월 20일쯤에 나올 예정이라고 합니다. 포트는 지금 퇴행 검사를 모두 통과하는 것을 확인했기 때문에, 릴리스된 당일 바로 갱신할 예정입니다.
서지원님께서 이제 훈련을 마치고 돌아오셨기 때문에, 제너레이터 익스프레션이 활발하게 진행되고 있는데요. 원래 5월 첫째주에 CVS에 들어갈 계획이었지만, 아직도 얼리-바인딩, 레이트-바인딩, 거의-레이트-바인딩 세가지 갖고 국론(?)의 분열이 엄청나게 심했기 때문에, 순조롭지만은 않은 상황입니다. 현재 저와 Raymond의 리뷰가 끝났고, 바이트코드 컴파일러 전문가인 Jeremy에게 리뷰 요청이 들어갔는데, 그 후에 아마 들어갈 수 있을 것으로 보입니다. Guido가 강력하게 만표를 행사하고 있는 의견은 거의-레이트-바인딩 인데, print >> None 의 동작에서 의 선택처럼 제일 헷갈리고 초보자들을 놀라게 만드는 선택이기는 하지만, 우선은 많은 경우 편리하게 사용할 수 있고, 자세한 동작을 신경 써야 할 정도의 코드면 심플 제너레이터로 풀어서 쓰라고 주장하고 있습니다.
devel/decompyle 이 2.3용으로 부활. 한참 2.2용으로 남아있었던 decompyle을 어느 의욕적인 해커가 2.3용으로 고쳤습니다. 원래 decompyle홈페이지에는 반영은 안 되어있는데, 고친 사람의 홈페이지에서 받을 수 있습니다.
[재미있는 파이썬 무림 소식] -1/1000은 왜 -1인가: 최근 c.l.py에 "어느 오래된 C 프로그래머"가 -1/1000이 다른 C 컴파일러들에서는 0인데 왜 파이썬에서는 -1이냐는 것에 대해서 의문을 올렸습니다. 그에 대해, C의 역사하면 뭐 거의 말 그대로 호랑이 담배피던 시절부터 생생한 현장에 있었던 Tim이 i / j의 나머지값은 반드시 0보다 크거나 같고, j보다 작다는 조건을 만족하기 위해서는 몫이 -1이고, 나머지가 999으로 나오는 것이 맞다고 "파이썬 첫 릴리스를 하기 전"에 귀도와 합의 했다는 답장을 올렸습니다. 그에 대해 다시 다른 사람들이 C99에서는 -1로 나오는 것이 표준으로 채택되어있다고 반발하자, Tim은 역시나 특유의 산신령적인 어투로, C89에서는 어느 것을 쓸 지 정해져 있지 않았고, C99가 그런 "이상한(wrong)" 방법을 채택한 것은 포트란과의 호환성을 위한 것일 뿐, 아무 이유도 없다고 했습니다.
요즘 영 머리 안 쓰는 일만 했더니 머리가 굳어가는 기분이 들기 시작해서, 2.4에서 새로 들어가는 collections 모듈의 heap타입을 한 번 구현해 보고 있습니다. heap타입은 일단은 피보나치 힙으로 구현하도록 제안되어있는데, 나중에 같거나 좋은 복잡도를 갖고 아모타이즈드 분석에서 나은 알고리즘이 있다면 다른 걸로 교체할 수도 있다고 합니다. 그래서 일단은 일반적인 힙 작업들을 메쏘드 인터페이스로 만드는 것이 가장 먼저 정해져야할 작업입니다.
옛날에 역시 피보나치 힙으로 구현된 파이썬 모듈인 devel/py-pqueue 소스를 봤을 때 앞쪽 주석이 "이 알고리즘은 매우 더러우니 소스 보고 이해할 생각은 하지 마시오" 식의 문구가 써 있어서 당황해서 안 봤던 기억이 있는데, 웹에서 애플릿 애니메이션을 몇개 보면서 문서를 보니 그런대로 이해는 가는군요. 요즘 세상이 좋아져서.. 흐흐;
우선, insert, min, extractmin은 구현했는데, 이제 decreasekey, union, iterator, delete같은 것만 구현하면 될 것 같습니다. 그런데, 지하철에서 오는 내내 생각하다가 내릴 곳을 놓칠뻔 한 심각한 고민이 문서들을 읽어봐도 해결되지 않는 것이 하나 있습니다. decreasekey 작업을 수행할 때 트리를 가지에서 뚝 떼서 밑둥에 붙이는 작업이 일어나는데, 그럼 그 원래 붙어있던 자리의 degree가 틀린 값을 기록하고 있게 된다는.. 그러니까 원래 degree 4인 것과 degree 1인 자식들이 붙어있던 녀석은 degree가 5가 기록이 되어있겠지만, degree 4인 자식이 decreasekey하던 중 떨어져 나가면, 그 가지는 실제로는 degree 2지만, 값은 5가 기록되어 있게 된다는 것인데.. 이렇게 되면, consolidate하는 과정에서 전체 원소 개수로 추정하는 maxdegree를 넘어 버리는 노드가 나올 수도 있을 것 같고, 무지 컸다가 막 decreasekey되면서 뚝뚝 떨어져 나온 힙이라면, 여기저기 실제 degree보다 엄청 높은 녀석들이 분산돼 있어서, 실제 효율이 많이 떨어지지 않을까 하는 걱정에 휩싸입니다. -.-;;; 흐흐흑... 혹시 피보나치 힙과 친한 분들은 꼭 알려주세요;
-> 후기: 알고보니 degree를 제가 잘못 이해한 것이네요; degree는 높이가 아니라 그냥 자식 노드 갯수를 뜻하는 것이었네요~ (아히 부끄러워라;; )
파이썬 마을은 지금 phpBB로 운영되고 있는데, 처음 도입할 당시에는 가장 적합했기에 쓰기 시작하기는 했지만, 아무래도 Zope나 Quixote같은 좋은 웹 프레임웍이 있는 파이썬 계열 사이트에서 계속 php를 쓰는 것은 좀 찝찝~~해서 바꾸려고 계속 생각하고 있었습니다.
오늘 찾아보니 phpBB 비슷한 형태의 Zope 기반 게시판 프러덕트가 fcForum과 CMFBoard를 찾았습니다. 구글 검색 결과로는 CMFBoard가 4배 정도 참조가 많이 된 걸로 봐서는 CMFBoard가 CMF의 후광덕에 좀 인기가 좋은 듯 합니다.
대충 웹에서 보니 둘 다 괜찮은 것 같아서, 앗싸~ 하고 깔아봤는데, 아 이럴수가 흐흐.
CMFForum - 속도가 굉장히 느립니다. 데모 사이트를 봤을 때 유난히 느리길래, 회선이 안 좋은가 했더니, 실제 깔아 보니 상상을 초월하게 느렸습니다. -o- 코드는 다른 CMF 프러덕트들처럼 엄청난 수의 (거의 20개에 육박) 의존 프러덕트가 있어서 그런지, 코드는 상대적으로 많이 간단했고, 관리도 수월해 보였습니다. 국제화 프레임웍이나 템플릿도 아주 잘 돼 있어서 유지보수성에서는 아주 좋아보였는데.. 그렇지만 Plone 때문인지 도저히 참을 수 없을 무거운 동작은 참..;;
fcForum - 상대적으로 속도가 아주 빠르고, CMFForum과는 다르게 캐쉬구조도 채택하지 않았음에도 거의 10배는 빠르네요. 그렇지만, 다른 일반 프러덕트들과는 달리 코드를 모두 Script (Python) 타입 오브젝트로 작성하는 바람에, 코드를 직접 설치되는 폴더에 복사해버리기 때문에, 심지어 프러덕트를 지워버려도 작동합니다. (인스톨용 프러덕트 --;) 그리고, Zope외에는 쿠키관리하는 간단한 프러덕트만 의존하고 있어서, 깔기도 참 편하긴 한데, 국제화가 Script 하나 안에 if 로 묶여있는데다가, 조잡한 다국어 지원을 넣고 있어서, 유지보수가 아주 힘들어 보였습니다. 그리고, 각 페이지들은 스크립트들 1개씩이 할당되어 있어서, 뭔가 한꺼번에 코드를 수정하기도 힘듭니다. -.- 므흐 결국은 뭐 PHP+Smarty구조랑 어느 정도 비슷한 것인데, 코드 자체의 문제를 빼고는 겉으로는 관리 인터페이스도 아주 훌륭하고 속도도 빨랐습니다.
CMFForum은 느려서 쓰기가 무리이고.. fcForum은 아주 쓰기는 좋은데 코드가 유지보수가 불가능해보이고 국제화 문제가 있어서, 고민을 좀 더 해 봐야겠습니다~
ACCU 2004 컨퍼런스에서 Armin Rigo씨가 발표한 프리젠테이션이 엄청난 반향을 일으키고 있습니다. 그래 파이썬 프로그래머라면, 프리젠테이션이 이정도는 해야하는건가!
화면이 뭔가 좀 이상하죠? 바로 PyGame으로 애니메이션 프리젠테이션을 만든 것! 시작하면 Rigo Production로고가 나오면서;; 레밍이 무턱대고 걸어가면서 걸어가다가 풍 빠지는데, Penty(Pentium assembly얘기 일까요?)는 그냥 무식하고 경로대로 걸어가다가 크래쉬난다고 그럽니다. 그 뒤에 보글보글이랑 높은 레벨에 나오는 귀신이랑 캐릭터가 퐁퐁 뛰어다니면서 소스가 1줄 1줄 진행될 때마다 CPy와 Psyco등이 각각 내부적으로 어떤 일이 있는지 자세히 알려줍니다.
으흐. 그동안 평범하고 정적인 프리젠테이션으로 알아보기도 힘든 발표를 늘 하고 있었는데, 이렇게 애니메이션으로 설명하니까, 머리에도 쏙쏙 들어오고 진짜 최고입니다. 파이썬이 아니라면 어느 커뮤니티에서 이런 시연을 볼 수 있을까요. ^.^ 저도 이제 pygame을 열심히 배워서;; 다음 프리젠테이션에는 꼭;; Armin도 사실 그동안 많이 psyco에 대해 설명을 해 봤지만, 이번에 최초로 청중들이 이해했다는군요;; 크흐;;
업동씨 결혼식갔다가 와서 시간이 좀 남아서 PEP309에 제출된 다른 언어의 "curry" 함수를 훔쳐온 아이디어, partial을 한번 구현해 봤습니다. 요즘 회사에서 HTML그리기 등등 잡무만 했더니 집에서 생산력이 아주 높아져서.. 언젠가 Ken Thompson씨던가가 말씀하셨듯, 역시 회사에서 잡무가 늘어날 때가 오히려 창의적 성취는 늘어나는 묘한 관계가 있는건지도요 -.-a
partial은 nohmad님의 말씀에 따르면 C#에도 partial이란게 있는데, 여기의 partial과는 좀 다른 버추어 메쏘드 만으로 이뤄지는 클래스 비스무리한 것을 뜻하는 키워드라는군요.. PEP309의 partial은 함수 호출의 일부만을 미리 정의해서 callable object로 만들어주는, anonfunc나 operator.itemgetter랑 약간 비슷한 류의 도구입니다. 예를 들면
요런 식으로, partial의 첫번째 인자는 함수이고, 두번째부터는 인자랑, 키워드 인자들이 들어갑니다. 그러면, 그 인자들이 함수에 나중에 적용되게 되는데, sorted의 원래 reverse 키워드의 기본 값이 False인데, 요렇게 True로 바꾼 것을 쉽게 만들 수 있겠죠~
partial은 타입 인자가 fn, args, kw 세개가 있는데, 셋을 만들고 나서 바꿀 수도 있습니다. 예를 들면,
파이썬 2.3에서는 본격적으로 소스코드 인코딩을 지원하기 시작해서 이제 소스코드 안에서도 u'한글' 이런식으로 C 처럼 한글을 유니코드로 바로 쓸 수 있게 되었습니다. 그런데, 인터랙티브 인터프리터 환경에서는 무조건 ISO-8859-1로 인식해 버리는 바람에, euc-kr 터미날에서는 이런 사태가 벌어집니다.
분명히 stdin의 인코딩은 euckr인데! 그걸 갈갈이 쪼개서 iso-8859-1로 넣어버리는 것인데, 사실 50명이 넘는 파이썬 개발자 중에서 iso-8859-1로 쓸 수 없는 모국어를 가진 사람은 2~3명밖에 안 되는 터라, 아무도 사실을 모르고 2.3에서 넘어간 것 같기도 하고.. (사실 iso-8859-1을 변수이름에 쓸 수 있는 꽁수도 있습니다. 흑흑 -.-...)
하여간, 그래서 이 문제를 해결하기 위해서 좀 삽질을 해 본 결과, 인터랙티브 인터프리터는 1줄씩 Parser/tokenizer.c의 tok_nextc함수에서 tok->prompt가 != NULL일 경우에 들어가는 루프에서 처리되는데, 파일에서 소스를 읽는 경우는 StreamReader로 처리하고 있는 반면에, 프롬프트에서 읽을 때는 전혀 디코딩 처리를 안 하고 있어서 결국은 iso-8859-1로 하고 있는건데, 일단 decode->encode하도록 약간 수정을 해서 트래커를 제출했습니다. 소스 파일에서 읽을 때는 Stream으로 읽은데 반해, 프롬프트에서 읽을 때는 조각 조각 디코드, 인코드를 하도록 했기 때문에, hzgb같은 행간 시퀀스가 있는 경우에는 완전한 지원이 불가능하지만, 사실상 그런 인코딩을 터미날에서 쓰는 사람은 없다고 봐도 괜찮다는 판단으로 그냥 저렇게 만들었습니다. -ㅇ-; (hzgb를 대체 어떻게 지원하지!;;)
아직 리뷰는 안 되었으니, 혹시 2.4 쓰고 계신 분들은 패치를 받으셔서 한번 테스트해봐 주세요 (처음 테스트를 도와주신 nohmad님께 감사~)
>>> u'한글' # 기본으로 euc-kr이나 utf-8같은 로캘을 쓴다면 유니코드 직접 쓰기 가능
u'\ud55c\uae00'
>>> import sys;sys.stdin = open("configure")
>>> u'한글' # sys.stdin이 stdin이 아닌 다른 것으로 교체된 경우에는 iso-8859-1로 폴백.
u'\xc7\xd1\xb1\xdb'
므흐흐. 스택리스 파이썬 개발자로 등록되었습니다. 며칠전에 amd64로 포팅한 것 때문에 해볼텨라고 메일이 와서, 별로 스택리스 내부는 잘 모른다고 고사했는데, 티스머씨가 그냥 하고 싶은 것만 하면 된다고 해서.. ^^;;
앞으로 스택리스 컨텍스트 스위처를 sparc64, ia64로 포팅하는 것같이 시시껄렁한 일을 일단은 주로 할 예정입니다.~ 아 근데 오리지널 파이썬과는 달리 쉘 계정도 주고 IMAP 계정도 주고 서비스는 짱이네요~ 므흐흐.. 근데 LC_ALL=C 로 바꿨는데도 자꾸 에러메시지가 독일어로 나오는 쉘이란 참;;;
작년 Miguel의 MS메일링에서의 Jim Hugunin의 메일 인용 공개를 시작으로 PyCon까지 엄청난 파장을 일으키고 있는 IronPython, 올해 OSCON에서 100달러 내기를 겨루게 되는 Parrot Pie-Thon, 혼자 만들었다고는 믿기지가 않는 8bit CPU를 위한 pymite 등등 정말 재미있는 파이썬 구현들이 많아지고 있습니다. +_+
그러는 와중 이제는, esoteric 계열 언어까지 하나 등장했습니다. 사실 완전히 escoteric 계열은 아니고 그쪽에서 놀던 사람들이 -.-;; 이름은 Prothon, Prototype Python을 줄여쓴 것이라는군요. 특징은 그동안 파이썬을 조금만 쓴 사람이면 다 불평하는, 완전한 쓰레드 지원 (fine-grained locking, object locking)이 들어갔고, lua 5에서도 도입하고 요즘 한창 인기인 스택리스 시스템으로 구현되었으며, 가비지 콜렉션이 CPython처럼 부가적인 마크-앤-스윕 이 아니라 바닥부터 마크-앤-스윕 으로 쓰레드마다 돌아갈 수 있도록 되어있다고 합니다. 사실 pymite에서도 그랬고, 파이썬을 새로 만들겠다 하는 사람들이 다 쓰는 특성이 아닐까 합니다. 크흐;
또한, Prototype Python 이름에서 풍기듯, Prototype-based Language를 표방하고 있다는 점에서 클래스 기반인 Python과는 좀 다르다고 하기는 하는데, prototype-based랑 class-based의 차이가 뭔지 아직 잘 모르겠습니다. -ㅇ-; (전에 들었는데 까먹었다 ㅠ.ㅠ) 그리고, 인덴트 제한이라던지, int형이 이터러블하고, /* */ 주석이 추가되고 등등 엄청나게 많은 문법 수정이 가해졌는데, 이건 참신한 시도이긴 하군요. 실험적인 독자 문법이 시장에 나와서 실제 사용자들의 반응을 볼 수 있는 좋은 기회인 듯 합니다.
그리고 독특한 특징 하나는 포터빌러티 레이어를 위해서 아파치의 APR을 썼다는 것입니다. 기존에 공개된 오픈소스 포터빌러티 레이어라면 glib이나 모질라의 nspr같은 것도 있긴 하겠는데 아무래도 라이선스 문제상 apr이 좋긴 하겠지요.. 그런데 apr은 영 거시기 한 것이 약간 거부감이 들기는 합니다. ;;
아직 프리알파 상태라서 지원 모듈이 극소수만 있다고 하는군요. 있다가 퇴근하고 해봐야겠습니다.
올해 초부터 쭉 파이썬 기본 객체들의 최적화 작업을 해오면서 거의 전체적으로 20%정도의 성능을 끌어올리는 전공을 세운 레이먼드 헤팅거씨가 다른 사람들이 시도해 볼 만한 재미있는 해킹꺼리들을 자세히 쓴 Raymond's List를 공개했습니다. (그는 제 멘터이기도 합니다. ^_^;; -- 괜히 우쭐 한번 ㅠ.ㅠ)
최근에 서지원님이 많은 해킹을 하고 계시는 컴파일러/VM쪽 외에도 기본 타입/라이브러리 쪽으로도 전체적인 상황을 몰라도 해 볼만한 것들이 많이 있네요. 열정이 넘치는 분들은 다 같이 해 봅시당~
얼마전 python-dev메일링에 올라온 "Who cares about the performance of these opcodes?"에 대한 amk의 답변에 -O3보다 -Os가 더 빠르다는 글을 보고 몇가지 테스트를 해 봤습니다. 파이썬 바이트 코드를 실행하는 Python/ceval.c는 거의 1000라인에 육박하는 switch-case문으로 구성되어있는데, 요즘 LIST_APPEND같은 특화된 옵코드를 계속 추가하면 전체적으로 switch-case가 느려지지 않겠느냐하는 글에 딸려 나온 것입니다.
오오. 그런데, 테스트를 해 보니 정말로 amk 말 대로 ceval을 -Os로 컴파일한 것이 더 빠른 것이었습니다.
Pentium3 550
Pentium4 Xeon 2.4G
-O3로 전부 (Python 기본 배포 디폴트)
12284
23616
ceval만 -Os
12379
23970
-Os로 전부
11615
18713
-O로 전부 (FreeBSD 포트 디폴트)
11594
이야. 캐쉬 히트나 브랜치 프리딕션 히트 때문인 것인지 궁극의 최적화 옵션 -O3보다 비실비실 -Os가 더 빠른 것입니다! 이건 단순히 1%도 안 되는 성능 향상을 컴파일 옵션으로 얻을 수 있다는 뭐 그런 의미보다는 switch-case문만 잘 줄이면 속도를 더 빨리 만들수 있다는 것을 암시해 주는 것! JIT를 사용하지 않는 파이썬 VM에서는 옵코드 개수가 역시 속도에 큰 영향을 미친다는 것이군요.
요즘 Raymond가 리스트, 딕셔너리, 컴파일러 등등 여러가지 최적화를 해서 정말 파이썬 2.4는 1.5 속도를 따라잡고 멋진 릴리즈가 되지 않을까 하는군요. 기대가 됩니다. 그리고, 컴퓨터 아키텍처 책 말고 실전에서도 코드 크기가 영향을 미친다는 것도 신비롭네요. -S옵션으로 풀어놓고 좀 더 연구를 해 봐야겠습니다. -ㅇ-;
lang/python 포트가 2.3에 처음 올라왔을 때는 멋있게 보이려고 --enable-shared를 디폴트로 짠!하고 넣었다가. 파이썬 공유 라이브러리의 진실에 대해 깨닫고 다시 static으로 잽싸게 바꾸었는데, static이 단순하고 빠른 면은 아주 좋은데 몇가지 문제점이 최근에 많이 제기 되었습니다. 흐흐
파이썬을 엠베드하는 컨슈머들이 몽땅 정적라이브러리를 링크해버려서, 파이썬 업그레이드할 때 같이 안 딸려 올라가기 때문에 호환성 문제가 생길 수 있고, 파이썬 버전 올라갈 때 마다 고역이다. (대부분의 의견)
ia64나 amd64같이 PIC바이너리와 non-PIC바이너리가 전혀 링크조차 안 되는 플랫폼에서 PIC바이너리 링크를 제공해 주기 위해서 결국은 static까지도 PIC로 컴파일해야해서 static으로 하는 득이 많이 줄어든다.
쪼끄만 프로그램에 커다란 파이썬 정적 라이브러리를 붙이려니 괜히 낭비다.
정적 라이브러리는 동적 라이브러리에 대한 의존성이 기록이 안 되기 때문에, www/mod_python3 같은 포트에서 동적 라이브러리에 대한 의존성이 무시되는 바람에, pthread라이브러리를 같이 물고 들어올 수가 없다.
등등.. 아우성이라서 결국은 빌드방식을 약간 바꿔서 정적빌드를 몽땅 한 다음에, 서브디렉토리에서 make 의 VPATH 변수 기능을 이용해서 libpython2.3.so와 python-shared만 빌드하도록 수정했습니다. 그래서 결국은 빌드 시간이 1/3정도 길어졌는데, shared 옹호파와 static 옹호파 양쪽을 모두 만족시키는 방법은 이것밖에 없다싶어서 Y.Y
그래서 이제는 곧 기본 파이썬 포트에서 bin/python 바이너리 외에 bin/python-shared 바이너리도 설치하게 되는데, python-shared는
FreeBSD JKH (Junior Kernel Hackers list)나 GNOME love day처럼 쥬니어 해커들이 입문하기 위한 도움이나 리스트 같은 것은 막 입문하려는 해커들에게 큰 도움을 주는 것 같습니다. GNOME love day 같은 것은 다른 데서도 앞으로 많이 했으면 좋겠네요.
그런 의미에서 한국어를 쓰는 쥬니어 파이썬 해커들이 해 볼만한 파이썬 해킹꺼리를 좀 정리해 봤습니다. 관심 있으신 분들은 한 번 도전을.. 서너개 정도만 말끔히 처리하면 파이썬 소스가 아주 익숙해지면서 금방 커밋 권한도 얻을 수 있을 것입니다~
다국어 식별자(internationalized identifier): 1월에 Martin v. Löwis의 메일에서 나온 아이디어인데, 아직 PEP나 구체적인 스펙이 나오지는 않았습니다. Martin의 의견으로는 tp_dict에 아스키로 인코딩 가능한 경우엔 string, 불가능한 경우에는 유니코드 객체를 집어넣어 버리고 그와 그와 관련된 함수들을 추가하자고 하고 있습니다. 그렇지만, 이렇게 되는 경우에는 u'abcd'와 'abcd'같이 같은 값이 서로 다른 키로 저장될 수도 있고, 일일이 구분해서 갖고와야 하는 수도 있고 해서 하위호환성 문제가 있는데, UTF-8로 저장하는 방법 등 몇가지 다른 처리 방법이 있을 수 있습니다. 파이썬 전체에 다국어 식별자 패치가 들어가면, 한글로 변수이름과 클래스 이름들을 쓸 수 있게 되기 때문에, 비영어권 사용자의 입문에 큰 도움이 될 것입니다. _ 그냥 단순하게 UTF-8만 되게 만들어 놓은 패치는 http://openlook.org/tmp/i18nidentifier.diff 에 있습니다.
크로스 컴파일: 848910 에 패치가 올라와 있기는 한데, 2.2.1기준으로 되어있고 무지 오래된 패치라 제대로 돌아가지 않습니다. 특히 ARM이나 PowerQUICC같은 기종에서 파이썬을 쓰시는 분들에서 유용한데, 크로스 컴파일 지원을 넣기 위해서는 일단 pgen 빌드 과정을 호스트와 타겟을 분리해야하고, setup.py에서 크로스 빌드를 약간 특별하게 취급해서 옵션을 넣어줘야합니다.
collections와 itertools, statistics: itertools는 2.3에 추가되었고, collections와 statistics는 2.4에 들어갈 모듈인데, 세 모듈은 늘상 쓰는 프로그래밍 패턴을 아주 단순화시켜준다는 면에서 매우 매력적입니다. 지금 들어가 있는 것들도 어느정도는 있지만, 자기가 쓰는 다른 패턴들이 더 있다면 추가해 보는 것도 재미있을 것입니다.
순파이썬 로캘 지원: 현재 파이썬에서 지원하는 locale과 관련 모듈들은 모두 시스템 로캘에 의존하고 있어서 요즘 엄청난 이슈가 되고 있는 time.strftime 문제처럼 시스템 독립성에 많은 문제가 되고 있습니다. .NET이나 Java처럼 언어 자체 지원으로 로캘을 지원할 수 있다면 플랫폼 독립성에 큰 도움이 되겠죠. 이 문제에 관심이 있으시다면 IBM의 ICU를 참고로 하시면 됩니다.
CNS-11643, HKSCS지원: 파이썬에 들어가 있는 CJKCodecs는 지금 널리 쓰이는 CJK 인코딩 중에 EUC-TW, ISO2022-CN같은 CNS-11643을 사용하는 인코딩들과 HKSCS의 지원이 빠져있습니다. 잠재적으로 대만과 홍콩 사용자들에게 문제가 될 수 있어서, 언젠가는 지원을 추가해야합니다. 이쪽 인코딩 정보에 대해서도 ICU 소스에 자세히 나와있습니다.
UTF-8 코덱 StreamReader.readline 수정: 현재 파이썬 UTF-8, UTF-7코덱의 StreamReader.readline은 전혀 제대로 동작하지 않는 상태입니다. 그런데, 딱히 깨끗한 해결책이 없기때문에 어쩔 수 없이 그냥 놓인 상태인데, 파이썬 코드로 10줄 내외이기때문에, 한번 뛰어들어볼 만 합니다.
sre모듈 C로 번역: sre모듈 중 일부는 굉장히 속도가 요구되는 부분임에도 불구하고 현재 파이썬으로 구현되어있어서 C로 번역하자는 여론이 어느정도 조성되어있는 상태입니다. 파이썬 소스 코드가 311줄정도이기 때문에, 이것과 기존에 C로 구현된 _sre를 합쳐서 한개의 모듈로 만들면 속도 상 많은 이익을 얻을 수 있습니다.
repr, sys.displayhook 국제화: 한/중/일 사람이 파이썬에 입문할 때 가장 헤메는 부분 중의 하나인 "리스트 속에 들어간 한글 제대로 안 보이는 문제"를 해결하는 원초적인 방법입니다. displayhook은 repr에 어느정도 의존하기 때문에, repr만 인코딩을 지원하도록만 수정해주면 됩니다. 그런데, 파이썬 내부의 tp_repr은 인코딩 정보를 전혀 받지 않기 때문에, 하위 호환성을 위해서는 tp_richrepr등의 이름으로 객체에 인코딩을 받아서 인코딩에 맞는 정보를 리턴해 주는 가공이 필요합니다.
MinGW 지원: 파이썬 2.4부터는 VC 7.1을 기준으로 윈도우 빌드가 바뀝니다. 아직 MinGW에서 파이썬을 빌드하려면 아주 어려운 수동 작업을 몇몇 거쳐야하는데, 이를 깔끔하게 정리해서 메인으로 들여오면 아주 멋지겠죠~
I've been in more than one heated argument about where the braces
in C/C++ should go and I’m sure that Python programmers are 10% more
productive just because of the time they don’t spend arguing about K&R
indenting style versus others.
-- Game Scripting in Python, by Bruce Dawson
번역하자면,
그동안 나는 C나 C++에서 중괄호를 어디에 써야 하는지 과열된 싸움을 봐왔다.
그리고, 파이썬 프로그래머들은 K&R 인덴트 스타일과 다른 스타일 사용자들과의
싸움에 허비할 필요가 없다는 점에서 적어도 10%는 더 생산적이라고 생각한다.
흐흐 그동안 K&R 인덴트가 아닌 프로젝트에 몇번 참여했던 경험으로는 충분히 10%는 넘는다고 봅니다. 어찌나 신경이 쓰이던지.. ㅠ.ㅠ
최근 ETech 2004에서 Nokia의 CTO가 Nokia의 차세대 핸드폰인 66 시리즈에 파이썬을 플랫폼으로 써서 핸드폰 애플리케이션들을 개발하고 있다고 합니다. 노키아가 작년에 1억대의 핸드폰을 세계적으로 판 것을 생각해 보면, 66 시리즈가 출시되면 파이썬 사용자가 대략 적어도 수천만명은 늘어나는 것인가요?
어제 python-dev에 Raymond가 자극적인 제목의 메일 Optimization of the Year을 올렸습니다. 내용은 예전부터 논란이 되어왔던 list.append류의 크기가 변하는 list에서 매번 realloc 을 호출해서 리스트의 성능이 크게 떨어진다는 것이었는데, 이번에 Raymond가 realloc을 안 쓰고 할당된 크기를 구조체에 저장하고 필요한 경우에만 alloc하는 걸로 바꿈으로써 realloc 이 느린 시스템에서 엄청난 성능 향상을 가져오게 되었습니다.
제 기계에서는 전체적으로 15%정도 가속이 되고, list.append는 2배로 최적화가 되었군요! 정말 좋습니다~ 그런데, 원래 Raymond의 구현에서는 list 구조체에서 내용을 저장하는 포인터인 ob_item이 외부에서 변경되는 것을 알아채기 위해서 ob_item을 따로 한벌 더 저장해 두게 되어있는데, Guido와 Tim은 앞으로 객체 추상화는 더욱 더 빡빡하게 될 것이니 외부에서 ob_item을 바꾸는 것은 도저히 용서할 수 없다는 뭐 그런 의견을 얘기하는군요. 그리고, Tim은 Raymond의 구현에서 멤버 변수가 3개나 추가돼서 리스트의 메모리상의 크기가 너무 커지는 것이 아닌가 하는 가이드까지 하며, align때문에 32비트 플랫폼에서는 공짜로 1개까지는 추가할 수 있다는 저같은 초보자는 상상도 못한 얘기를.. 정말 Tim의 무공은 바닥이 보이지 않는 바다입니다. 대단해요~ -.-b
하여간 그래서 제가 약간 고쳐서 1개만 쓰고, tracked를 제거한 패치를 올렸더니 대충 만족하는 분위기라 곧 커밋될 것 같습니다.~ 이제 2.4에서는 2배 빠른 list를! 크크크
지난번에 공약했던 대로(;;;;) CJKCodecs를 드디어 파이썬에 집어넣었습니다! 꺄아~ 파일이 워낙에 많아서 커밋 로그 편집기만 2페이지가 넘고, 그놈터미날 버퍼 사이즈를 넘쳐서;; 뒤로도 못 돌아가는 엽기적인 사태가 흐흐;; 그리고 파이썬 커밋메시지 최초로 160KB짜리 메시지가 갔습니다. _-_
여하간, 이제 파이썬 2.4에서는 더이상 한글 코덱을 따로 깔 필요가 없으며, 일본어나 중국어도 마찬가지입니다. ~.~; 그러나, 앞으로도 당분간은 파이썬 2.1, 2.2, 2.3을 위한 써드파티 모듈 지원도 계속할 계획이고, 올해 말 안에 HKSCS(홍콩)과 EUC-TW(대만) 지원을 넣을 넣을 계획입니다.
CJKCodecs를 파이썬으로 넣기 위한 패치를 올렸습니다. 잇힝. 약간 토론을 거쳐서 넣을 수 있으면 넣을 작정입니다. 아마도 전에 Barry와 Martin이 동조를 해 줬기 때문에, 별로 어렵지 않게 들어갈 수 있을 것 같은데.. 일본어코덱 유저들의 반발이 있을지도 모르니.. 헉헉. 일본 사람들 안 보는 사이에 몰래 넣어놓고 버티면.. 흐흐;
지원님께서 드디어 PEP289를 구현한 패치를 소스포지에 올리셨습니다. 우와~ 제가 BNF ambiguity 해결하고서는 놀고 있었더니 먼저하시다니 =3 =33 크크.. 파이썬 정규 문법 구현 패치로는 한국인 최초이기에 지원님이 자랑스럽습니다. (괜히 친한 척 해본다;; )
몇가지 테스트해 보니까 PEP에 명시된 스펙은 모두 잘 되는 듯 합니다.
>>> x = 'merong'
>>> list(x*y for x in range(10))
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
>>> (x for x in range(10))
<generator object at 0x82a81bc>
>>> x
'merong'
>>> (x for x in 1, 2, 3)
File "<stdin>", line 1
(x for x in 1, 2, 3)
^
SyntaxError: invalid syntax # (요건 listcomp 비호환성)
이야 정말로 PEP에서 보던 것 보다 훨씬 좋네요. 크크 패치를 리뷰한 다음에 빠른 시일 내에 커밋하도록 할 생각입니다. 지원님도 곧 파이썬 개발자로.. =3 =33
1달 전쯤에 있었던 python-dev에서 토론 중에 나왔던 바로 그 연산자를 받으면 전부 함수로 만들어버리는 걸 그냥 모듈로 한번 만들어 봤습니다. 사실은 operator모듈에 넣고 싶었지만, 선행 연산자에 변수가 있으면 발생하는 모호성이나 체이닝 콜 같은 게 너무 심각해서 표준에 넣었다가는 돌맞을 것 같아서 으흐~;;
원래 파이썬에서 import 하면 모듈이 존재하는 곳을 맨 먼저 찾고, 표준 서치 패스를 찾게 되어있습니다. 그런데, 얼마 전 Raymond의 크리스마스 소원 목록에서 등장해서 엄청난 이슈를 일으키고 있는 명시적 상대 경로 임포트 (explicit relative import)가 이제 뭔가 대세가 되고 있군요.
중간에 문법과 구현 원리가 엄청 많이 제시되기는 했지만, 대충 지금까지의 의견 수렴은
'.'를 기본 sys.path에서 뺌 (지역 디렉토리에서의 단순 임포트 불가)
from의 패키지명 앞에 . 1개를 쓰는 경우 지역 디렉토리, 2개이상을 쓰는 경우 상위 디렉토리를 찾음.
이렇게 되어가고 있는데, 여기서도 구체적인 문법 모양 등의 사안에 대해서는 의견이 아직 분분하군요. 예를 들면 현재 같은 디렉토리에 있는 파일을 임포트할 때 import what하면 될 게, 이제 앞으로는 from . import what이 된다는.. 상위 디렉토리의 다른 패키지 모듈을 임포트 하는 경우에는 from ..subdir import what 이런식으로 일단은 될 모양이군요. (아직 결정은 안 됨)
이 이외의 의견으로는 이런 것도 있습니다. (다들 나름대로의 지지자들을 확보. )
상위 디렉토리에 올라갈 때 .대신 __parent__를 쓰고 현재 디렉토리에서 임포트할 때에는 __here__에서 임포트
상위 디렉토리에 올라갈 때 ../../ 식으로 슬래쉬를 넣자는 의견
그냥 상대경로 임포트를 놔둔 채로 표준 경로에서 임포트할 때 from stdlib import xxx로 하자는 의견
며칠 전 Miguel의 블로그에 올라온 블로그가 크게 파장을 일으키고 있네요. Jython 개발자인 Jim Hugunin이 .NET 기반의 새로운 파이썬인 Iron Python을 만들어서 Microsoft 내부 메일링 리스트에 결과를 올렸는데, 예전의 Active State의 구현이나 Parrot계열의 Pirate의 실망스러운 결과와는 완전 상반되게 70%나 CPython보다 빠르다는 결과를 얻었다고 합니다. (원본 메일 (Miguel의 복사본))
특히나 function call, integer add쪽은 CPython에서 엄청난 오버헤드가 있는 것으로 유명했던 부분이라.. 역시나 IL asm으로 직접 번역하는 것으로 구현된 Iron Python보다 엄청나게 느린 것으로 결과가 나왔군요. 그리고 range의 경우에는 메모리 할당이 단편적으로 엄청나게 일어나기 때문에 CPython이 유리한 게 나왔고 eval("2+2")쪽은 CPython은 컴파일러가 순수 C로 구현되어있기 때문에, 흐흐..
하여간 .NET IL asm으로 직접(C# 안 거치고) 파이썬 코드를 번역하면 아무래도 CPython보다 더 빠르지 않을까 생각하던 초기 .NET 개발자들의 예상은 대충 맞았다는 것이 증명되고 있는 듯 합니다. 아직 Iron Python이 많이 구현되지 않은 반면 최적화를 수행하지 않았기 때문에, 앞으로 변동이 좀 있을 것 같기도 한데.. 하여간 무지 기대가 되네요. (MS에 팔아먹으면 대략 낭패 --; )
한편, Iron Python이 오픈소스가 아닌 MS나 다른 회사의 상용 제품으로 들어가는 것을 대비해서 최적화를 계획해야할 텐데, CPython도 이제 슬슬 표준 환경에서의 JIT 지원에 대해서 본격적으로 진지하게 고려해 봐야 할 것 같기도 합니다. (PyPython은 아직 까마득.. 으흐...)
포트 PR이 올라왔길래 한 번 해봤습니다. 흐흐 IPython은 예전에 나왔던 devel/py-repl 같이 파이썬 인터랙티브 인터프리터 프론트엔드인데 오토 컴플릿 같은 몇가지 유용한 기능을 추가로 지원하는 녀석입니다. py-repl이 국제화가 제대로 안 된 것에 비해 IPython은 그래도 국제화도 잘 되어있고, 다국어지원도 대비되어 있네요.
젤 독특한 것은 젠투 만큼이나 화려한 칼라인데.. -.- 프롬프트가 녹색이고 에러는 빨간색이고 아주 난리가 납니다. 흐흐 아아 그런데, 왜 정작 신택스 하이라이트는 안 되는거야!! ㅎㅎ ;; 정말 아쉽네요~
오리지널 파이썬의 것 보다 인덴트도 좀 더 똑똑하고, import c<tab>누르면
In [5]: import c
callable class cmp compile continue credits
chr classmethod coerce complex copyright
요렇게 임포트 할 수 있는 모듈 이름도 나오고.. 흐흐 py-repl보다 대체로는 만족스럽군요. 한글도 잘 되구요. 신택스 하이라이트만 되면 정말 좋을텐데~~ 크크
홈페이지는 http://ipython.scipy.org/ 이고, 포트에는 devel/ipython 으로 등록하려고 원 PR 저자에게 메일을 보냈습니다. 그 사람은 devel/py-ipython으로 만들었는데, 아무래도 모듈로 쓰이는 게 아니니까 그냥 py-를 안 붙이는 게 나은 것 같네요
Guido가 몇 년째 열심히 반대하다가 얼마전에 드디어 들어간 list.sorted와 얼마전 블로그에서 얘기했던 itertools.groupby에서 아주 유용한 itemgetter와 attrgetter가 얼마전에 추가됐습니다. 원래 lambda로 처리해야하는 건데 아무래도 lambda만 들어가면 일단 거부감이 들기 때매.. 흐흐...
예를 들면 원래 [(10, "merong"), (20, "hoho"), (30, "abcd")]를 순서대로 정렬하려면
므흐흐.. 좋기는 한데, 뭔가 itemgetter랑 attrgetter는 너무 한군데만 특수화되었다는 느낌을 지울 수 없는데, 다시 메일링 리스트에 Michael W. Hudson이 엄청난 팁을 하나 공개했는데, 요렇게 쓴다고 합니다. (정확히는 이 코드는 Thomas Heller가 mwh의 사용법을 보고 추리해서 짠 것..)
class Adder:
def __init__(self, number):
self._number = number
def __call__(self, arg):
return arg + self._number
class X:
def __add__(self, number):
return Adder(number)
X = X()
print map(X + 1, range(2))
즉, X + 1 하면 + 1하는 순간에 Adder인스턴스가 생성돼서, +1하는 객체로 둔갑을 해서 결국 웬만한 것은 lambda 없이도 쓸 수 있게 된다는.. 크크 정말 멋지네요 +_+. 그런데, 이 방법에서는 X.split('.') 같이 아래 어트리뷰트를 호출하는 건 코드가 실행되는 때가 먼저 와 버리기 때문에 제대로 동작하지 못하게 되는데, 몇가지 껍데기를 씌우면 되기는 되겠네요..
음.. 하여간 대부분의 경우에 정말 멋지게 동작해서 mwh의 이 아이디어는 아주 멋져보입니다.~
저는 파이썬 2.3에서 추가된 모듈 중에 개인적으로 가장 좋아하는 모듈을 꼽으라면 단연 itertools 모듈을 꼽겠습니다. itertools 모듈은 C나 Pascal같은 고급 언어들이나 기타 스크립트 언어들 대부분에서 마저도 지저분하게 처리가 되는 for/while/do-while 등의 루프 패턴들을 정말 간단하게 정리해 주는 데 엄청난 효용을 자랑하는데, 예를 들어 파일에서 START로 시작하는 라인부터 읽고 싶다면 옛날 구현에서는 보통:
for line in fo:
if line.startswith('START'):
break
else:
return # START가 없음
(..line 처리.. START로 시작했으므로..)
for line in fo:
.. 본 처리...
그런데 이제, itertools를 쓰면
for line in itertools.dropwhile(lambda x: x.startswith('START'), fo):
... 본처리 ...
으흐흐흐.. 그 외에 여러개의 이터레이트 가능한 객체들을 연결해서 한꺼번에 처리해주는 chain이나 여러번 재활용하게 해주는 cycle, 일정회수 반복하게 해주는 repeat등 유용한 것이 정말 많습니다. +_+
그런데, 엊그제 귀도가 샤워 중에 groupby라는 새로운 이터레이터 패턴을 만들었는데 요것도 정말 쓸모가 많은 듯 해서 한번 대장금 보면서(;;;) 구현해 보았습니다. (패치는 여기) groupby는 모인모인의 TitleIndex 같은 페이지에서 정말 지겹게도 쓰이는, 인덱스별 분류 패턴을 간소화를 시켜주는데, 보통 이런 짓을 하려면 이렇게 구현하겠죠.. 문자열이 가득 든 소팅된 x 리스트를 첫자를 기준으로 줄을 그으려면
group = (None, [])
for s in x:
if group[0] is not None and group[0] == s[:1]:
group[1].append(s)
else:
print "----"
for gm in group[1]:
print gm
group = (s[:1], [s])
구현이야 되지만, 뭘 하려는지 코드만 대충 봐서는 한눈에 들어오지도 않습니다. 흐흐.. 근데 요걸 새로운 groupby 이터레이터를 쓰면 간단하게 되는군요! 꺄아
for it in itertools.groupby(lambda i: i[:1], x):
print "----"
for s in it:
print s
뭐하는지도 눈에 보이고 구현도 간단하고.. 정말 좋네요.. +_+
한글 글자들을 초성 기준으로 분류하는 것도 이렇게 간단하게 됩니다.
import itertools, hangul
s = '가각간곽나냥뇽당당둥돼래릴'.decode('utf-8')
for it in itertools.groupby(lambda h:hangul.split(h)[0], s):
for c in it:
print c.encode('utf-8'),
print
요렇게 하면 결과는
sbtm(perky):~/cvs/itertools% python test.py
가 각 간 곽
나 냥 뇽
당 당 둥 돼
래 릴
귀도도 말했듯, 이터레이터와 제너레이터 장난은 정말 코드 간소화에는 엄청난 도움을 주는 듯 합니다. 앞으로도 재미있는 이터레이터가 2.4에 많이 추가되길..
CJKCodecs에 그동안 오랫동안 있었던 일본어 호환성 문제가 대충 잡힘에 따라, 다음 주 중으로 1.0.2를 릴리즈하려고 합니다. 혹시 CJKCodecs에서 아주 사소한 문제점이라도 발견하신 것이 있으면 릴리즈 전에 꼭 알려주세요.. 이번주 토요일이나 일요일 쯤에 내놓으려고 합니다. 1.0.2가 아무래도 1.0 브랜치에서는 마지막이 될 듯 합니다.
현재까지 예정된 1.0.2에서의 수정 사항은:
str.encode에서 메모리에서 바로 인코드해 버리는 문제 수정
shift-jis 코덱에서 '~' (틸드)가 인코딩/디코딩이 안 되는 호환성 문제 수정 (사실 원래 법대로 하자면 틸드는 JIS X 0201에는 없기 때문에 안 되는게 맞지만, JapaneseCodecs에서는 0x80이하를 그냥 아스키 영역에 매핑하고 있기 때문에 호환성 때문에..)
shift-jis 코덱에서 U+FF3C (FULL-WIDTH REVERSE SOLIDUS)를 매핑하지 않는 문제 수정.
ISO-2022-JP-EXT 코덱 추가
강태욱님의 cp933 코덱은 아직 문제점이 해결되지 않은 듯 해서, 아무래도 1.1 브랜치로 넘겨야 할 것 같네요..
PEP 289 제너레이터 익스프레션은 2002년 1월에 처음 제안되어 얼마전에 파이썬 2.4에 채용하기로 결정된 문법입니다. 파이썬 2.0에서 도입된 리스트 컴프리헨션의 제너레이터 버전이라고 볼 수 있는데, 리스트 컴프리헨션이 전체 리스트를 일일이 다 만들어서 넘겨주기 때문에, 한꺼번에 실행되는터라 부하도 크고 메모리도 무진장 먹습니다. 요 문제를 해결하기 위해 제너레이터로 만들어주는 건데.. lambda와 list comprehension의 중간쯤 된다고 볼 수 있겠군요.. 흐흐.. 예를 들면, 리스트 컴프리헨션에서는 요렇게
sum([x*x for x in range(10000)])
10000개 원소의 리스트를 한꺼번에 다 계산해서 더하게 되는데, 제너레이터 익스프레션에서는
sum(x*x for x in range(10000))
이렇게 하면, 이게 제너레이터로 변신해서 sum함수에서 1개씩 이터레이션 할 때마다 실행되게 됩니다. 흐흐 만세~
그런데, 이 문법은 아무래도 모호성 문제가 있는데
a = (x for x in "abc") # 요건 valid
b = x for x in "abc" # 요건 invalid (괄호가 없음)
f(x for x in "abc") # 요건 valid. 예외적으로 함수 호출같이 괄호가 밖에 있으면 허용
f([x for x in "abc"]) # 요건 그냥 리스트 컴프리헨션..
c = [x for x in "abc"] # 요것도 리스트 컴프리헨션..
d = [(x for x in "abc")] # 요건 제너레이터 익스프레션이 들어있는 리스트
이런식으로 뭐 결과적으로는 맞긴 한데.. 뭐 하여간 모호하긴 하군요.. 흐흐
자 그럼 제너레이터 익스프레션을 본격적으로 맛볼 시간!
# 시그마 x=0부터 9까지 x^2를 모두 더함
print sum(x**2 for x in range(10))
# 0부터 99까지 3의 배수들의 평균값을 구함
print average(x for x in range(100) if x % 3 == 0)
# x, y가 각각 0과 10사이일 때 곱이 10의 배수인 것 중에 x+y가 가장 큰 쌍
print max((x+y, x, y) for x in range(11) for y in range(11) if x * y % 10 == 0)[1:]
하하 대단 -.,-;;
흐흐.. 그런데, 아직 PEP289 는 구현이 안 나와있어서 시험해 볼 수는 없는데 Jeff Epler가 yield가 앞에 들어가는 옛날 형식 문법으로 구현한 compiler 패키지 기반으로 된 것만 나왔습니다. 그래서 진짜 파이썬에서 쓰는 parser 모듈로 구현을 한 번 해보려고 하고 있는데 문법이 야릇하다보니 문법 구현부터가 힘들군요 --; 일단 패치는 다음과 같이 만들어 봤는데.. arglist가 아무래도 test 토큰이 앞에 argument가 *로 붙은거랑 겹치다보니.. ambiguity가 자꾸 발생하는군요.. 이것 어떻게 해결해야할 지 --;;; -ㅇ-; BNF 잘 아시는 분께서는 좋은 의견이 있으시면 알려주세요~♡;;
Python 2.3에 weakref와 gc에 관련된 치명적인 버그가 발견되어 방금 고쳐졌습니다. 발생하는 경우는 이렇게 그냥 간단한 코드에서도 볼 수 있습니다.
import gc, weakref
def test():
class J(object):
pass
class II(object):
def acallback(self, ignore):
self.J
I = II()
I.J = J
I.wr = weakref.ref(J, I.acallback)
del I, J, II
gc.collect()
test()
I -> I.wr -> I.acallback -(strong ref) -> I 이런 식으로 J와 II사이에 사이클릭 레퍼런스가 일어나는 데 중간에 몇개가 weakref로 되어있지만, 파이썬 2.3에서 완전히 도입된 new style class의 gc에서 weakref를 전혀 처리를 하지 않고 있어서 죽어버린다는군요.
lang/python 포트에는 이 패치를 넣기 위해서 portmgr에게 허락을 요청해 놓았습니다. (어제부터 프리즈 -.-;;) 그리고, Tim Peters는 메일에서 올해 안에 2.3.3 릴리즈를 하자고 하고 있네요. 파이썬 개발자들은 세그폴트 정도는 신경 안 쓰는 줄 알았더니 -ㅁ-;;;
apply(), coerce(), intern() 내장 함수 셋이 압도적인 지지로 deprecate결정되고 있습니다. apply의 경우에는 이미 deprecation상태인데, 셋 다 그래도 내장함수이기 때문에 다음 릴리즈에서는 조용한 warning, 그 다음엔 시끄러운 warning, 그 다음엔 진짜 삭제 정도의 과정으로 지워질 듯한 전망입니다.
얼마전에 강태욱님께서 알려주신 빈 문자열을 str.decode 메소드를 이용해서 디코딩할 때 에러가 나는 문제를 수정한 CJKCodecs 1.0.1을 릴리즈했습니다. 그 외에, ISO-2022-JP-2 코덱이 G2에 할당되는 ISO-8859-1(서유럽알파벳), ISO-8859-7(그리스알파벳)을 처리하지 못하던 문제도 수정하였습니다.
아마 이번 버그 픽스로 ninix-aya나 orange-slice에서 발생했던 문제가 모두 해결되지 않을까 생각됩니다.
Python 2.3 라인의 새로운 버그픽스 버전인 2.3.1이 릴리즈되었습니다. 이번 2.3.1 릴리즈는 2.3이 발표된 직후 발견된 몇가지 치명적인 버그들과 숨어있던 메모리 누수를 많이 잡았습니다.
FreeBSD lang/python 의 업데이트는 지금 4.9 릴리즈를 위한 semi-frozen 상태이므로 업데이트가 어렵고, 한 1주일 안에 업데이트할 수 있을 것 같네요. 제 컴퓨터에서는 일단 test도 모두 성공하고 있습니다. (i386) 그런데, sparc64에서는 몇개 실패하고 amd64에서는 크래쉬나는 게 몇개 보이네요.
CJKPython은 어제 2.3.1-RC로 잠시 작업을 했는데, 내일 중으로 CJKPython 2.3.1을 릴리즈할 수 있을 듯 합니다.
윈도우용 한/중/일 전문 파이썬 개정 배포본인 CJKPython 2.3.1a1을 릴리즈했습니다. 이번 버전에서는 전의 릴리즈에서 실험적으로 채택했던 wxPython과 Boa Constructor를 라이센스 문제로 제거했고, 다시 파이썬 표준 배포본처럼 Tkinter와 IDLE를 넣었습니다. 그리고, 인스톨시에 바이트 코드를 컴파일하기 때문에, 시스템관리자가 아니더라도 빠르게 파이썬 프로그램들을 실행할 수 있게 하였습니다. 전의 버전에서는 사실 SJIS 패치가 안 들어갔었는데 이번엔 빠짐없이 다 넣었습니다.
얼마전 OnLamp에 Guido van Rossum과의 인터뷰가 올라왔습니다. 얼마전에 귀도가 Zope를 떠나서 다른 회사로 간다고 발표한 것도 있고, 2.3과 2.3.1얘기도 있고 해서 인터뷰 내용이 아주 재미있는 게 많네요 그동안 파이썬 문법이 계속 복잡해지면서(관점에 따라..) CP4E를 포기한 것인가! 하고 주장하는 사람도 있었는데, 아직 Guido는 CP4E가 어느 정도는 지금도 말이 된다는 입장이군요 으흐흐;;
If you say, "Why should a programmer learn Python",
I could say, "Because it's the most fun of all the available languages".
--- ''Guido van Rossum''
ActiveState에서 만든 구리구리한 Python.NET 말고 Zope에서 만들고 있던 PythonNet이 Preview 2가 발표가 됐군요~. 아직까지는 MS.NET CLR하고만 제대로 돌아가지만, Mono로도 곧 되지 않을까 싶습니다. 흐흐
타볼을 풀어보면 빌드하기는 좀 아리송 하고 (뭔가 싸인을 하려면 인증서가 있어야 한다는데, 배포는 같이 안 하는군요) 바이너리가 들어있어서 그걸로 실행해 보면 됩니다.
짠 실행해 보면
>>> from CLR import System
>>> System.Console.WriteLine("우헤헤헤 {0} 짜짠짠 {1}", 100, "oops!")
우헤헤헤 100 짜짠짠 oops!
>>> from CLR.System import Text
>>> Text.Encoding
<class 'CLR.System.Text.Encoding'>
>>> import sys;sys.platform
'win32'
흐흐 Jython 처럼 뭐 플랫폼이 바뀌는 것은 아니고, 그냥 일반 CPython과 CLR의 중간 연결고리만 만들어 놓은 녀석이라, 플랫폼은 그냥 네이티브로 나옵니다. 그리고, 파이썬 바이트 코드들은 .NET 어셈블리로 바뀌어서 실행되는 게 아니라, 전부 CPython VM이 실행하고 중간 데이터 교환만 PythonNet이 담당해서 CLR에게 전해지게 됩니다.
이미 해본 분들은 아시다시피 ~.~, 파이썬 2.3에서는 --enable-shared를 주면 공유 라이브러리로 사용이 가능하도록 돼서, libpython2.3.so가 1메가짜리가 나오고 python은 3천 바이트짜리가 나옵니다.
그래서, 이야 멋지다 하고 메모리 절약에 도움이 되지 않을까 하는 생각에, FreeBSD포트 lang/python 에는 덥썩 shared를 디폴트로 해 버렸는데, 다행히도 python-dev 메일링에 누가 "왜 --enable-shared가 디폴트가 아닌가요"하는 질문에 Martin v. Löwis가 좋은 대답을 해 주어서, 덕분에 잘못 알고 있었던 것을 바로 잡게 되었습니다. 으흐흐 (다들 알던 것인가;;)
웬지 공유 안 할 것 같아 보였던, static 바이너리도 inode가 같은 경우에는, text 이미지를 메모리에서 모두 공유한다는군요 (두둥!) ~.~;;
Löwis의 가르침(!)을 요약하면..
파이썬 바이너리가 1개만 있으면, 걔네들은 모두 공유라이브러리 만큼 전부 메모리나 디스크 공간을 공유한다. 그런데, 거의 대부분의 파이썬 애플리케이션들이 파이썬 바이너리를 따로 쓰는 게 아니기 때문에, 대부분의 파이썬 애플리케이션들은 실행 파일 이미지를 메모리에서 공유한다고 볼 수 있다. 특별한 예외라면 mod_python이 있는데, mod_python은 아파치 바이너리를 통해서 공유돼서, 다른 파이썬 바이너리와는 공유하지 않지만, 아파치 바이너리들 끼리 공유해서 같은 효과를 얻는다.
공유 라이브러리를 유지하는 것은 상당한 관리상 문제점이 따른다. 어떤 경우에는 인스톨이 제대로 안 될 수도 있고, 공유라이브러리 링커에 따라 못 찾게 될 수도 있다.
공유 라이브러리를 사용하면, 시작하는 시간이 길어진다. 또한, ld.so에 디렉토리가 몇 개 더 추가되어야 하고, 빌트인 모듈로 컴파일되지 않은 파이썬 모듈까지 모두 공유라이브러리 패스에 들어가야 한다. (퍼키 주: 이 부분은 적어도 FreeBSD에서는 사실이 아닙니다. FreeBSD에서는 그냥 dlopen(3)으로 절대경로찾도록 되기 때문에, 정적 컴파일한 것이나 같습니다.)
공유 라이브러리를 사용하면, 실행 시 효율성이 떨어진다. PIC (Position-Independent-Code)는 일반적으로 non-PIC 바이너리보다 최적화에서 불리하다. (블루님 주: 현실적으로는 거의 차이가 없다고 합니다. ;)
공유 라이브러리를 들고 있으면, 관리 비용이 더 많이 든다. 컴파일러, 링커, 다이내믹 링커 등등 거의 모든 개발 툴에서 기존에 없었던 문제가 발생될 수 있고, 이에 대해서 일일이 고려해야한다.
흐흐흐. 그래서, FreeBSD의 lang/python 포트도 별도의 공유 라이브러리 포트를 분리해 내고, 정적 컴파일로 다시 돌리려고 합니다. 만세 \(-.-)/
지난 번에 string repr과 string print를 로켈에 맞게 수정한 버젼이 pickle같은 몇 가지 곳에서 문제가 발견되어 CVS에 들어갔다가 빠졌는데, 새로운 방법을 여러 모로 생각해 봤지만, 적당한 방법이 생각이 안 나서, 결국은 type object에 tp_richrepr 이라는 메쏘드를 새로 만드는 방법을 한 번 생각해 봤습니다.
파이썬에서 오브젝트가 출력되는 방법은 두 가지인데,
PyFile_WriteObject에서 출력하는 오브젝트가 진짜 파일인 경우에는 PyObject_Print로 직접 FILE *fp에다가 출력. PyObject_Print는 재귀적 탐색을 해서 String의 경우에는 PyString_Print가 내부 함수인 string_print를 호출해서 최종적으로 출력하는 데, 이 때에 flags에 Py_PRINT_RAW가 세팅되는 경우에는 그냥 fwrite를 하기 때문에 한글이 제대로 나오는데, 0인 경우에는 한글이 모두 이스케이프되어 버림.
PyFile_WriteObject에서 출력하는 오브젝트가 StringIO같은 가짜 파일인 경우에는 PyObject_Repr로 일단 String으로 만든 뒤에 그 녀석을 인자로 해서 출력 오브젝트의 write를 호출.
여기서, 첫번째 방법으로 출력이 되는 경우에는 그다지 어렵지가 않은 것이, Py_PRINT_RICH라는 플래그를 하나 만들어 줘서, 그 녀석을 계속 끝의 flags에 달아 다니다가, PyString_Print와 PyUnicode_Print에서만 적당히 처리해서 뿌려주면 될 것 같습니다.
그런데, 이제 두번째 경우에는 repr()이 호출되어서 PyObject_Repr에 들어온 것인지, 출력하려고 PyObject_Repr에 들어온 것인지 하위 오브젝트들에게 전달해 줄 수 있는 방법이 전혀 없기 때문에, 결국은 새로 오브젝트 프로토콜 메쏘드를 하나 만들어 주는 수 밖에 없는 걸로 보입니다. 그래서, 결국 typedef PyObject *(*richreprfunc)(PyObject *v, const char *encoding); 타입으로 하나 만들어서 typeobject의 제일 끝에 추가하고 PyObject_RichRepr을 PyFile_WriteObject에서 사용하도록 하려고 생각하고 있습니다.
아직은 가능성을 위해서 이것 저것 테스트해 보고 있구요 ~.~; 우선, CJKPython 2.3final에서 표준 2.3과 호환성을 유지하기 위해서는 타입 오브젝트의 크기가 변할 수 없기 때문에, SJIS 패치에서만 그냥 원래 일본식 repr을 쓰고 표준 타입에서는 sys.displayhook만 교체하는 방법을 쓰려고 합니다.
파이썬 2.4에서는 다국어 문제가 말끔히 해결되었으면 좋겠네요. 혹시 좋은 아이디어 있으신 분들은 꼭 알려주세요~
Apple의 MacOS X 10.3 Panther의 출시에 맞추기 위해서 7월 31일 이전에 발표하기로 했던, Python 2.3이 활발히 진행 중입니다. 몇 가지 주된 이슈들을 정리하면..
-Kthread 옵션이 실패하지 않는 문제: -Kthread를 지원하지 않고 C 컴파일러가 쓰레드 라이브러리를 별도로 요구하는 FreeBSD, NetBSD, MacOS X 같은 환경에서 5월부터 configure하면 -Kthread 테스트부분이 실패는 하지만, 실제로 gcc가 에러를 리턴하지 않아서 결국은 -Kthread가 없는데도 -Kthread를 써버리는 문제가 있었습니다. FreeBSD의 lang/python-devel 포트는 이에 대해서 로컬 패치을 쓰고 있었는데, Skip과 Martin이 열심히 이리저리 해본 후에, 딱히 -Kthread의 실패를 감지할 좋을 방법이 없어서, 그냥 따로 kthread 옵션을 플랫폼마다 configure에서 처리해 주기로 했습니다.
Cygwin에서 쓰레드 문제로, 멎어버리는 현상: Cygwin의 sigmask의 구현의 자체 버그로 인한 것으로 밝혀졌으며, 그에 대한 대응 패치가 들어가서 해결되었습니다.
BSDDB3가 윈도우와 리눅스에서 멎어버리는 현상: bsddb3가 쓰레드를 쓰는 프로그램에서 제법 불안한 것으로 실험되었습니다. 대부분의 경우 큰 문제는 없지만, 그래도 트랜잭션을 완전히 걸어주면, 웬만큼은 해결된다고 합니다.
zipimport: zipimport가 zip앞에 쓸데없는 데이터가 섞여 있는 경우, zipfile모듈과는 달리 읽지 못하는 문제가 있다고 합니다. 그렇지만, 이미 파이썬 2.3이 RC상태이므로, 이것을 '기능'으로 처리할 것인지, '버그'로 처리해서 고칠 것인지 얘기가 있었는데, '버그'로 결정이 난 듯 해서, 지금 HEAD에는 고쳐져 있습니다.
Mac: 이번 릴리즈를 서두르게 된 이유가 된 맥 환경에서도 인스톨러 문제를 비롯한 몇 가지 문제가 있었는데, 열혈 pyobjc 멤버들과 Jack의 노력으로 대부분이 해결 되었습니다.
브랜칭: FreeBSD와는 달리, Python은 베타와 RC를 별도 릴리즈 엔지니어링 브랜치에서 하지 않고, HEAD에서 합니다. 따라서, 브랜칭은 Python 2.3 final이 나오고나서 HEAD 브랜치가 2.4가 되고, 2.3은 23-maint 브랜치로 들어가게 됩니다.
잘 안 알려진 (에.. 적어도 제 주위엔;;) 유용한 파이썬 디버깅 팁을 하나 소개합니다~
보통 파이썬 스크립트 테스트할 때 스크립트를 실행해서 익셉션이 발생하면 트레이스백을 보고 대충 상황을 추측하거나 예외난 부분 근처에 print를 잔뜩 써서 해결하게 됩니당. (디버거로 들어가기 힘든 부분에 들어갈 때..)
근뎅, 파이썬의 -i 옵션을 쓰면 요 문제를 바로 깔끔하게 해결할 수 있습니.. 으흐흐흐. 꺄아~* 다음 스크립트는 dict.get을 쓸 때 자주 발생하는 타입 에러 중 하나인뎅 봅시당~
1
2
3
#!/usr/bin/env python
d = {'hello': 5}
print d.get('hello') + d.get('kitty')
하면 당연히 d에 'kitty'가 없기 때문에 int+None해서 타입에러가 납니다. 근데, 요게 무지 긴 프로그램에 들어 가고 막 코드가 흩어져 있으면 깨나 애를 먹일 수 있는데, 파이썬에 -i옵션을 주면 다음과 같이 익셉션이 나자마자 바로 인터프리터가 떠서 상황을 볼 수가 있게 됩니당.
puppet(perky):~% python -i kitty.py
Traceback (most recent call last):
File "kitty.py", line 3, in ?
print d.get('hello') + d.get('kitty')
TypeError: unsupported operand types for +: 'int' and 'NoneType'
>>> print d.get('kitty')
None
>>> print d
{'hello': 5}
으훗~ 물론 뭐 인터프리터니까 함수 몇 개 실행해 볼 수도.. 파이썬 2.3b2부터는 PYTHONINSPECT 환경변수를 아무꺼나로 지정해 주면, -i 옵션을 안 쓰고도 인터프리터를 띄울 수 있습니다.
오늘 python-dev 메일링에서 --without-pymalloc 옵션을 주면 malloc/free와 관련된 비표준 문제가 생긴다하는 어떤 사람의 질문에 대한 Guido의 답변에 대한 Tim의 답변이 흥미로웠습니다.
[Guido]
I haven't heard of platforms where turning off pymalloc is required --
unless we hear about those, I expect that for 2.4, pymalloc may no
longer be optional. (The reason: maintaining two versions of the same
code is a pain, and usually the version that's not selected by default
is severely broken after a few releases.)
[Tim]
We never build without WITH_PYMALLOC defined anymore, so under the "if it's
not tested, it's broken" theory, it's already broken <0.5 wink>. OTOH,
there are really only two substantive WITH_PYMALLOC #ifdefs in the codebase,
and one of them just surrounds the bulk of the code in obmalloc.c. So as
untested features go, I bet this one is less problematic than
WITHOUT_COMPLEX (which is tested in many more places!).
역시 같은 기능에 대해서 두가지 옵션이 안정적으로 제공되려면 덜 매력적인 옵션이 디폴트가 되고 더 멋진 옵션이 선택사항이 되어야, 코드가 깨지는 것을 그런대로 막을 수 있다는 생각이 듭니다. (소비자의 테스터화 작전 -O-;;)