파이썬에서 순열을 구하는 몇 가지 방법

A~Z까지 알파벳으로 이뤄진 5글자 단어를 모두 검색해서 뭔가를 한다거나, 아들 이름 지을 때 성을 제외한 2글자에서 가능한 모든 조합을 하고 싶은 것 같은 경우가 있습니다. 여러 다양한 상황에서 전혀 주먹구구식 알고리즘이 안 나오고 그냥 NP-complete 문제를 위한 정공법으로 전수조사를 해야할 때면 순열을 만드는 것이 가장 간단한 경우가 많겠죠. 순열 만드는 것이 간단하면서도 뭐가 좋을지 고민을 좀 하게 만드는데, 그래서 파이썬에서 순열을 만들 때 쓸만한 방법을 대충 생각나는 것을 모아 봤습니다. ^_^

우선, 일반적으로 나오는 C언어 입문서에서처럼 다 풀어쓰기를 하면 보통 이런 식으로 구현될 것입니다.

뭔가 한 눈에 확 들어오는 간단함은 있지만, 반복 수가 변하는 경우에는 루프가 늘어나고, 별로 코드도 중복이 가득해 보이는 것이 그다지 멋있지 않습니다. 그래도, 일단 좀 더 파이썬 코드처럼 보이게 하기 위해 줄여 보면,

이제 1줄로 줄기는 했지만, 내부적으로는 구조는 1번과 다를 것이 없습니다. 반복횟수가 바뀌면 여전히 루프가 늘어납니다.
그래서, 루프를 1개로 줄이고, 보통 많이 쓰이는 나누기 나머지 나누기 나머지 방법을 쓰면 이렇게 약간 일반화를 할 수도 있겠죠.

루프는 1개로 줄었지만, 여전히 3개로 제한되어 있기는 마찬가지입니다. 이번에는 alpha에 매핑하는 부분도 일반화를~

자 이제 코드도 줄고 depth만 바꾸면 길이가 마음대로 바뀝니다~ 그렇지만, 약간 계산 오버헤드가 늘기는 했겠죠. -ㅇ-;

순열이 완전히 다 필요한 경우가 아니라, 일부가 필요한 경우이거나, 순열에서 쓰는 원소의 메모리 크기가 엄청 커서 복잡한 경우 등 여러 독특한 경우에는 순열에서 만들어지는 놈을 필요할 때 계산하는 것이 유용할 수도 있습니다.

자, 이번엔 접근법을 약간 바꿔서 숫자를 안 쓰는 방법을 생각해 봅시다. 빈 것에서 시작해서, 모든 경우를 한 번씩 추가한 것을 원하는 횟수만큼 계속 더해주는 방식으로 하면 되겠죠.

알고리즘의 계산 복잡도는 약간 안 좋아졌지만 — O(MN)에서 O(MN+2)로.. — 짧은 순열에 대해서는 그다지 차이는 안 날 것 같고, 코드도 그런대로 알아보기 쉬워졌습니다~ ^_^

이번엔 또 접근법을 좀 바꿔서, 행운을 믿는 사람이라면 순전히 랜덤 함수에 기대어 빨리 끝나기만 기다릴 수도 있겠습니다;;

전체 순열이 필요할 때 이걸 실제로 쓰게 되지는 않겠지만, 순열이 굉장히 커서, 전체를 메모리에 담고 있을 수 없을 때, 순간 순간 생성하되 랜덤한 순서가 필요할 때는 이것도 쓸모가 있겠죠;;; (억지로 짜낸 용례 -ㅇ-)

정말 심심할 때는 추후 고객의 업그레이드 유도를 위한 “바쁘게 돌아가는 인터넷 속의 쉼터”(TM)로 이렇게 만들어 볼 수도 있겠습니다;;

아하하;;;

자.. 이제 파이썬에서 순열을 구하는 여러가지 방법을 알아 보았는데요, 어느 한 방법이 꼭 좋다기보다는, 상황마다 고려해야할 것이 많이 있겠죠. 예를 들면,

  • 순열이 무지 길고 크고 루프가 오래 돌아간다 –> 순열을 생성하는 놈을 제너레이터로 만들어서 한꺼번에 메모리를 왕창 안 먹고 있게 한다.
  • 분산처리를 해야한다 –> 단일 숫자 인덱스를 기반으로 한 순열이 아무래도 쪼개기가 좋겠죠.
  • 항상 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외에는 디폴트로 안 만들어주겠다는 정책을 취하고 있어서 불편하다고는 하지만, 뭐 돌아가는 방법이 있으니까.. ^_^

파이썬 3000에는 어떤 것이?

최근 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뒤에 항상 괄호를 해야 한다는 것이고,
대략 보면 이렇습니다.

물론 대부분의 경우에 이걸 자동으로 번역해 주는 스크립트를 샤샥 돌리면 해결되지만, 한 가지 경우에 호환이 안 된다고 합니다.

이런 경우 예전에는 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 디자이너의 의도를 충분히 살려서 혼란을 없애고 싶은 경우를
위해, 키워드로만 받는다고 선언하는 문법이 생깁니다. 좀 문법이 희한한데,

로 쓰면, c와 d는 키워드 인자로만 받는다는군요;;

집합(set) 표기법

2.4에서 추가되어 굉장한 인기를 끌고 있는 set이 드디어 소스에서도 간단하게 쓸 수 있게
표기법이 추가됩니다. {1, 2, 3}으로 쓰면 set이 된다고 합니다. 즉, :가 없으면 set, :가 있으면
dict가 되는 것이죠. set comprehension도 물론 생깁니다. 흐흐

절대경로 임포트

파이썬 2.5에서 __future__로 숨겨져 있는 기능인데, 이제 패키지 경로의 혼란을 줄이기 위해서
패키지 내부에서 암묵적으로 상대적인 경로로 임포트가 가능하던 것이 금지됩니다. 이제 상대경로로
임포트를 하려면 . 이나 .으로 시작되는 다른 경로 이름을 써 줘야 하게 되었습니다.

문자열 포매팅

2.3인가에서 추가되었던 string.Template가 이제 표준 str타입의 % 연산자에서 지원되게 됩니다.

여기서 하나 궁금해 지는 것은, string formatting에서 항상
나오는 복수형 만들기 문제나 조사처리 같은 것을 써드파티에서
추가할일이 생길텐데요. 그런 경우를 위해서 사용자가 타입별로
제어할 수 있게 하거나 훅을 넣을 수 있게 여러 기능을 제공할 것 같습니다.

새로운 scope 선언자 nonlocal

파이썬 2.1에서 nested scope가 들어오면서 무척 편해진 것은 사실이지만 그동안 global과 local
밖에 없어서 상위 스코프가 global이 아닌 경우 상위 스코프의 뭔가를 건드리려면 list로 만들어서
넣는다던지 편법을 써야 했습니다. 이걸 위해서 스코프 블럭 앞에 nonlocal이라고 선언하면
이쪽에서 쓸 것은 아니니 nested된 윗쪽 스코프 것을 건드려라 하게 됩니다. 말로 들으면 복잡한데
실제로 사용한 예를 보면 나쁘지 않군요. 🙂

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 깊숙히! (상) 에 대한 몇 가지 변명

지난 번
파이썬 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개를 배치한 다음에, 약간 빠른 속도로 플레이하면서 각 팀들의 의견이나 토론이 있으면 서로의 의견 차이와 잘 모르는 것을 안 수줍게 해결할 수 있는 자리가 되지 않을까 싶네요. 아무래도 생방송보다는 녹화방송이 편안하니까 ^.^;

기계공학의 최적화설계이론을 보면, 설계상의 몇가지 선택지가 있을 때 각각의 최적조건을 계산해서 유전자알고리즘을 사용하거나 동적계획법을 사용하여 여럿 중에서 계속 선택해 나갑니다. 튜토리얼에서 실습해 보는 간단한 프로그램에서도 이런 것들을 적용해서, 어떤 루프를 쓸 것인가, 어떤 자료형을 쓸 것인가 뭘 먼저할 것인가 이런 의사 선택을 모두 나열한 다음 (물론 작은 프로그램이니까 가능) 다른 페어들이 모두 각각을 경험해 보고 그 언어의 특성에서 어느 것이 더 좋았는지 얘기해 보는 것도 좋을 것 같구요~

다음에 좀 더 길게 해 볼 기회가 생기면, 해 보고 결과를 알려드리겠습니다. ^_^

파이썬 GIL 깊숙히! (上)

대표적인 파이썬 구현인 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으로 증가시켜서 즉각적으로 다른 곳으로 넘겨버립니다. (그래서 이렇게 시그널 핸들러가 직접 호출되지 않는 경우가 있기 때문에,
시그널 핸들러가 희한하게 꼬인 상황에서 엉뚱한 예외가 발생한다거나, 시그널 때문에 예외가 씹힌다거나, 순서가 뒤죽박죽이 되는 일이 일어납니다.)

그런데, 쓰레드 수가 많을 때 실행되는 순서는 어떻게 될까요?
뭔가 내부적으로 정해진 것이 있으면 좋지만, 사실 파이썬에서는 시스템의
쓰레딩 라이브러리에 전적으로 맡깁니다. 즉, POSIX 시스템에서는
sem_post(3)/sem_wait(3) 또는
pthread_mutex_unlock(3)/pthread_mutex_lock(3) 쌍을 순서대로 호출해서, 그냥 아무데나 가도록 합니다.

그런데, 이게 쓰레드 구현마다 다르고 쓰레드의 종류마다 달라서, 일정한 동작이 있지 않습니다. 일반적으로 시스템 스코프 쓰레드들은 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에서 ④~⑤사이에 비어있는 부분은 갈색 블럭이 되어야 합니다.

Django 책

요즘 파이썬 웹계에서는 지난 주에 발표된 《The Django Book》이 굉장한 관심을 불러모으고 있습니다. 내년에 정식으로 출판될 책인데, 미리 독자들의 리뷰와 의견들을 모으기 위해서 인터넷에 본문을 공개한 것입니다.

종이로 된 책이 나오는 것 자체가 시장에서의 위치를 얘기해 주는 대략적인 지표를 넘어선 것이라고 볼 수 있어서 상당히 반가운 일이기는 하지만(최근에는 파이썬 수험서도 나왔죠! ^.^), 이 책에서는 공개한 방식이 무척 주목할 만 합니다.

우선, 전문을 한꺼번에 공개한 것이 아니라, 책의 일부씩 순차적으로 공개했다는 점이 중요한 듯 합니다. 전문을 공개했다면 이미 책이 완성돼서 출간되기 직전에 그냥 한번 입에 오르기 위한 것이 아닐까 하는 느낌도 들고, 사람들의 관심이 분산되었을텐데, 조금씩 조금씩 차차 공개함으로써, 사람들의 관심을 집중시킬 수 있으며 상호작용을 촉발시키는 중요한 계기가 된 듯 합니다.

또한, 웹 프레임워크답게 아주 편리한 웹 인터페이스를 제공해 주었는데요, 그동안 파이썬쪽에서 널리 쓰이던 Silva는 괜찮은 듯 하면서도 은근히 손이 점점 안 가게 되는 답답한 면이 많이 있었습니다. Django Book에서는 최근 유행하는 웹 기술들을 적용한 덕에, 점점 코멘트를 달고 싶어지는 UI를 잘 만들어낸 것이 아주 멋있습니다.

코멘트 시스템에 대한 설명을 보면, 개략적인 설명도 있는데 Yahoo! YUI를 썼다고 하는군요. 나중에 혹시 이게 범용으로 공개된다면, 책을 번역하거나 공개 리뷰를 하는 목적으로 매우 편리할 것 같습니다. +_+

제인 구달 박사 강연 『희망의 이유』

오랫동안 제 마음 속 영웅 중의 하나인 제인 구달(Jane Goodall)박사가 학교에서 강연을 해서 듣고 왔습니다. 생물학과 교수님들이 사람이 너무 적을까봐 걱정하면서 꼭 가보라고 얘기를 했는데, 막상 가보니까 빈 자리가 없을 정도로 꽉꽉 들어차서 간신히 자리를 하나 찾아서 앉았습니다.

사회자가 소개를 하고 앞으로 딱 나오는데, 옷이 탐험복 비슷한 것을 입으신게 아 막 눈물이 쏟아지려하는 감동이.. 울컥~ 우흐흐. 처음에 인사를 하시는데, 침팬지 언어로 “Hi~”를 하는데, 진짜로 실감나게 동물의 왕국에서 봤던 침팬지 인사를 구사하시더군요. 저 정도면 진짜 침팬지랑 말이 통하지 않을까 생각..

오늘 강연 내용은 뭐 대체로 그동안 책에 있던 내용이 요약되어 새로운 것은 없었지만, 그래도 그 연세에도 일년 중 300일 이상을 환경과 미래를 지키기 위해 이런 저런 강연과 만남을 갖고 계신 것을 보면 정말 대단합니다. 저도 30살되기 전에 칼슘을 많이 먹고 운동을 꾸준히 해야겠어요;;

그리고, 책에서 꾸준히 나왔던 종교적인 신념에 대해서 어떤 학생이 질문을 했는데, 이제 더 이상 공적인 자리에서 기독교인이라는 것을 밝히고 있지 않고 진화를 지지하지만, 신의 존재에 대해서는 믿고 있다고 합니다. 그동안의 책과 어조가 약간 바뀌신 것이 흥미롭네요. +_+

우흐흣. 싸인 받았습니다. 자랑 -.-vv (사람이 너무 많아서 이름은 안 써주시더군요; 아쉽;)

파이썬의 JIS Roman, KS Roman 문제에 대해

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는 표준 지원을 위해서 다음 몇가지를 진행할 계획이 있습니다.

  • CNS11643 캐릭터셋 통합 (현재는 CJKCodecs에만 있음)
  • iso-2022-cn, euc-tw 지원 (CNS11643 캐릭터셋이 있어야 함)
  • 일본 MS 확장 인코딩 표준 지원 (일본 Legacy Encoding 프로젝트 작업분 통합)
  • 일본 -strict 코덱 부활
  • Big5 확장 인코딩을 변경할 수 있게 매핑 오버라이딩 지원

으흐흐. 2.6 나오기 전까지는 할 거예요 =3=3