최근 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뒤에 항상 괄호를 해야 한다는 것이고,
대략 보면 이렇습니다.
1 2 3 |
print x, y -> print(x, y) print x, -> print(x, end=" ") print >>f, x -> print(x, file=f) |
물론 대부분의 경우에 이걸 자동으로 번역해 주는 스크립트를 샤샥 돌리면 해결되지만, 한 가지 경우에 호환이 안 된다고 합니다.
1 |
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 디자이너의 의도를 충분히 살려서 혼란을 없애고 싶은 경우를
위해, 키워드로만 받는다고 선언하는 문법이 생깁니다. 좀 문법이 희한한데,
1 |
def foo(a, b=1, *, c=42, d): … |
로 쓰면, c와 d는 키워드 인자로만 받는다는군요;;
집합(set) 표기법
2.4에서 추가되어 굉장한 인기를 끌고 있는 set이 드디어 소스에서도 간단하게 쓸 수 있게
표기법이 추가됩니다. {1, 2, 3}으로 쓰면 set이 된다고 합니다. 즉, :가 없으면 set, :가 있으면
dict가 되는 것이죠. set comprehension도 물론 생깁니다. 흐흐
1 |
{f(x) for x in S if P(x)} |
절대경로 임포트
파이썬 2.5에서 __future__로 숨겨져 있는 기능인데, 이제 패키지 경로의 혼란을 줄이기 위해서
패키지 내부에서 암묵적으로 상대적인 경로로 임포트가 가능하던 것이 금지됩니다. 이제 상대경로로
임포트를 하려면 . 이나 .으로 시작되는 다른 경로 이름을 써 줘야 하게 되었습니다.
문자열 포매팅
2.3인가에서 추가되었던 string.Template가 이제 표준 str타입의 % 연산자에서 지원되게 됩니다.
1 |
"See {0}, {1} and {foo}".format("A", "B", foo="C") |
여기서 하나 궁금해 지는 것은, string formatting에서 항상
나오는 복수형 만들기 문제나 조사처리 같은 것을 써드파티에서
추가할일이 생길텐데요. 그런 경우를 위해서 사용자가 타입별로
제어할 수 있게 하거나 훅을 넣을 수 있게 여러 기능을 제공할 것 같습니다.
새로운 scope 선언자 nonlocal
파이썬 2.1에서 nested scope가 들어오면서 무척 편해진 것은 사실이지만 그동안 global과 local
밖에 없어서 상위 스코프가 global이 아닌 경우 상위 스코프의 뭔가를 건드리려면 list로 만들어서
넣는다던지 편법을 써야 했습니다. 이걸 위해서 스코프 블럭 앞에 nonlocal이라고 선언하면
이쪽에서 쓸 것은 아니니 nested된 윗쪽 스코프 것을 건드려라 하게 됩니다. 말로 들으면 복잡한데
실제로 사용한 예를 보면 나쁘지 않군요. 🙂
1 2 3 4 5 6 7 |
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표시를 하면서 기다려 보세요. 🙂
더 관심이 있으신 분들을 위해 ==>
- 파이썬 3000에 대한 구글 TechTalk 비디오
- PyCon 2007에서 발표된 귀도의 기조연설 프리젠테이션
전 뭐 이제 막 파이썬에 익숙해지기 시작한 터라 그다지 큰 감흥(?)은 없네요;; 그런가보다-하고 따라가게 될 것 같습니다.
그나저나 print “x\n”, “y” 이런 기능이 있었으면 했는데 역시 있었고, 또 사라질 예정이라니..-_-;
잘 읽었습니다. ^^ 그런데 여러가지가 많이 바뀌긴 하지만 큰 변화는 없네요. Python 3K가 기존 브랜치에서 따로 나오는 이유가 뭔가요?
하위호환성이 보장되지 않기 때문입니다. 파이썬 2.x까지는 많은 분들이 그렇지 않게 느끼시기는 하겠지만, 하위호환성 유지하느라 고생 많이 했습니다. ^_^;
1. 예전에 parrot vm이 개발되어서 파이썬을 그 위에서 돌릴 때에, correctness를 보존하면서 둘중에 뭐가 더 빠를지를 테스트할 때에, print “x\n”, “y” 이 테스트를 귀도가 포함시켰다고 들었습니다. 장난스럽게 말했는데, 어쨋건 parrot 개발자가 엄청 화냈다더군요.
2. scope 관련된 키워드는 nonlocal로 결정된건가요? 이번 파이콘은 안가서 모르겠는데, 전에 어디선가 negative한 이름의 키워드라서 좀 꺼린다고 들었는데…
3. keyword only argument는 제가 구글에서 일할 때에 구현했습니다. p3yk branch에는 반영되어 있지요. ^^
4. 그외 자잘한 변화중의 하나로 reduce 내장함수가 없어졌습니다. 개인적으로 있었으면 했지만, 귀도가 파이썬은 functional programming language가 아니라고 하면서 필요하면 loop을 쓰는게 좋은거 같다더군요.
한참 동안 게으름증에 Python으로 개종하냐 마냐를 고민하다가 경전읽기(?)를
시작하고 보고 있는 C++교도입니다. 아… 한데 벌써 뭐가 이리 바뀝니까? ㅋㅋㅋ
요즘 개인적으로 20분안에 영상 합성용 Tool짜기가 가능한 Framework를
디자인하고 이를 구현하기 위한 개발언어로 Python을 써보려고 한답니다. 좌우당간 잘 써먹어야 되겠군요. 호환성 체크해놓도록 하겠습니다.
p.s:장혜식님의 블로그를 통해 김창준님 블로그도 가보게 되었습니다. 마치 두분을 보니 예전 역사책에서나 보던 같은 학파의 선비들을 보는 느낌입니다. 멋있습니다.
p.s2: naver 블로그에서 계속 http://openlook.org/blog/1147/something로 트랙백을 걸려 하는데 안되는 군요. 주고 오류라나? 어떻게 된걸까요? ㅋㅋ
서지원님: nonlocal에 대한 내용은 PEP나 메일링리스트 토론을 봐서는 특별한 내용은 못 본것 같아요~ PyCon에서의 분위기는 잘 몰라서 구체적으로 어떤지는 잘 모르겠네요 으흐; 그나저나 구글에서 인턴으로 그런 작업을 하셨다니 무척 부럽군요! 저도 귀도를 옆에 두고 뭔가 하나 만들었으면 좋겠는데 킁;
유진호님: 흐흐 사실 이 정도 규모로 바뀌는 것은 거의 파이썬이 생기고 최초이기 때문에 자주 바뀐다고 볼 수는 없어요~ 문법이 계속 추가되고 있긴 하지만, “바뀌는” 것은 드문 일이죠. ^^; 트랙백은 이글루스나 네이버에서 종종 안 되는 경우가 있다고 들었는데.. 언제 한번 해 봐야겠네요;
정말 감사히 읽었습니다. (__)
짧은 실력에 영어는 안되고, 오픈룩에 가끔 들려서 파이썬 3000소식을 읽을때마다 설레고 있습니다.