파이썬(Python) 3.0에서 새로운 점

** 파이썬 3를 완벽하게 이해하지 못한 부분에서 오류가 발생하는 것을 최소화 하기 위해 모든 부분에서 직접 실행을 해보고 적었습니다. 그래도 오류가 발생한다면 죄송합니다.

참고한 문서: http://docs.python.org/py3k/whatsnew/3.0.html
원저자: Guido van Rossum

1. PEP 3105 : Print Is A Function

  Print 구문이 함수로 바뀌었습니다. 함수의 원형은 아래와 같이 변경되었습니다.
print([object, ...], *, sep=' ', end='\n', file=sys.stdout)
  예를 들면 print "Hello, Python.", "I like Python" 과 같이 쓴 코드를 3.0 버전으로 다시 쓰면 print("Hello, Python.", "I like Python") 처럼 쓸 수 있습니다.

  그리고 sep 키워드의 값은 앞에 나온 객체들을 붙여 쓰는 방식을 지정합니다. 기본값이 ' ' 으로 되어 있으므로 위의 예에서는 Hello, Python. I like Python 처럼 쓰여지지만 sep='' 라고 지정하면 Hello, Python.I like Python 과 같이 쓰여집니다.
  예전에는 연속해서 나오는 문자열을 붙여서 쓸려면 print 문에서 바로 해결이 안됐지만 sep 의 도입으로 가능해졌습니다.

  참고로 더 이상 print 함수에서는 "softspace"가 지원되지 않습니다.
(softspace 란 print 문에서 컴마를 사용해서 한 줄에 입력할 때 자동으로 출력값 사이에 스페이스를 넣어주는 기능입니다.)


2. Views And Iterators Instead Of Lists

  몇몇의 API들이 더 이상 리스트를 리턴하지 않게 됐습니다. 먼저, 사전 객체의 메소드인 dict.keys(), dict,itmes(), dict,values() 는 views 객체를 리턴하게 됩니다. 따라서 k = d.keys(), k.sort() 와 같은 기법은 사용할 수 없게 됩니다. 대신에 k = sorted(d) 를 사용해야 합니다.

  참고로 views 객체는 사전에 존재하는 객체인데, 사전의 변경이 이들의 객체에 직접 반영됩니다. 예를 들어 a = {'one' : 1, 'two' : 2}를 하고, b = a.keys() 를 했을 때 a 값을 변경하게 되면 그 변경이 b 에도 영향을 미칩니다. 이 외에도 views 객체는 개개의 데이터를 산출하도록 반복될(iterated) 수 있고, 멤버쉽 테스트를 지원합니다.
  그리고 dict.iterkeys() 와 dict.iteritmes(), dict.itervalues() 메소드가 더 이상 지원되지 않습니다. 따라서 이들을 계속 쓰려면 keys나 items, values 메소드가 리턴하는 views 객체에 iter() 함수를 사용해야 할 듯 싶습니다.

  또, map()과 filter()는 반복자를 리턴합니다. 따라서 리스트를 반드시 얻어야 한다면 list() 함수로 리스트를 구해야 할 것입니다. 그리고 range() 함수가 임의의 크기를 갖는 값과 작동하는 경우를 제외하고는 xrange() 처럼 작동합니다. 따라서 xrange() 는 더 이상 존재하지 않게 됩니다. 마지막으로 zip()도 반복자를 리턴합니다.


3. Ordering Comparisons

  파이썬 3.0 에서는 비교 방식이 더 단순해졌습니다. 일반적으로 의미 없는 비교(<, >, <=, >=)를 가질 때 TypeError 예외를 일으키도록 변경 됐습니다. 예를 들어 1 < 'a', 0 < None 과 같이 예전에는 False 를 리턴했지만 3.0 부터는 에러를 일으킵니다. 따라서 각각의 요소들이 비교될 수 없는 리스트끼리의 비교는 에러를 일으키게 됩니다. 단, = 과 != 비교는 이 규칙을 따르지 않기 때문에 여전히 비교가 가능합니다.

  내장 함수인 sorted() 와 list.sort() 함수가 더 이상 cmp 인자를 받지 않습니다. 대신 key 인자를 사용해야 합니다. 그리고 key 와 reverse 는 오직 키워드만 받는 인자가 되었습니다.

  마지막으로 cmp 함수와 __cmp__() 메소드가 더 이상 지원되지 않습니다. 따라서 __lt__(), __eq__(), __hash__() 나 다른 비교 함수를 사용해야 합니다.

  그리고 cmp() 함수가 필요하다면 (a > b) - (a < b) 와 같이 사용하면 cmp() 와 동등하게 사용할 수 있습니다.


4. Integers

  long 이 int 로 이름이 변경되었습니다. 즉, 모든 내장 정수는 int 형 하나 뿐입니다. 그러나 여전히 long 형처럼 사용할 수 있습니다. 또, 1/2 와 같은 분수형 표현이 실수형을 리턴합니다. 만약, 예전처럼 정수값을 얻고 싶다면 1//2 와 같이 사용해야 합니다.

  그리고 정수형이 더 이상 제한이 없기 때문에 sys.maxint 상수가 제거되었습니다. 대신 sys.maxsize 를 사용해서 예전의 sys.maxint 와 같은 값을 얻을 수 있습니다. long 형이 제거 되었기 때문에 repr() 을 사용함으로써 long 형 뒤에 생기는 L 은 더 이상 생기지 않습니다. 마지막으로 8진수 형태가 0123 이 아니라 0o123 으로 변경 되었습니다.


5. Text Vs. Date Instead Of Unicode Vs. 8-bit

1) 파이썬 3.0부터는 문자열을 다루는 방식이 달라졌습니다. 예전과는 달리 모든 텍스트는 유니코드가 되었습니다.
(단, 인코딩된 유니코드는 바이너리 데이타로 표현 됩니다.)

  텍스트로 사용된 타입은 str 클래스이고, 데이타로 사용된 타입은 바이트 클래스입니다. 만약, 실질적인 사용법을 알고 싶다면 아래를 참조하세요.
http://diveintopython3.org/strings.html#byte-arrays

2) 파이썬 2 버전과 가장 큰 차이점이라고 하면 텍스트와 데이터를 섞으려는 시도가 있을 경우 TypeError 를 일으킵니다. 파이썬 2버전에서는 유니코드와 8비트 문자열을 섞으려고 하면 8비트 문자열이 아스키 코드이었다면 작동을 했지만 8비트 문자열에 비 아스키 코드가 있었다면 UnicodeDecodeError 를 일으켰습니다.

3) 모든 텍스트가 유니코드인 만큼 더 이상 u'...' 표현은 사용할 수 없습니다. 대신 바이너리 데이타에서는 반드시 b'...' 표현을 사용해야 합니다.

4) 텍스트와 바이트가 섞일 수 없기 때문에 서로 전환을 해야 하는데, 텍스트에서 바이트로는 str.encode() 나 bytes(s, encoding = ...) 를 사용하면 되고, 바이트에서 텍스트로는 bytes.decode()나 str(b, encoding=...)을 사용하면 됩니다.

5) 텍스트 표현이 변경 불가능인 것처럼 바이트 표현도 변경 불가능 입니다. 대신, bytearray라는 타입이라는 변경 가능한 타입이 있습니다. bytes 를 받아 들이는 거의 대부분의 API 들이 bytearray 도 받아들입니다. 변경 가능한 API 는 collections.MutableSequence 에 기본을 둡니다.

6) raw 형식의 문자열에서 모든 백슬래쉬가 문자 그대로 해석됩니다. 예전에는
ur'\u20ac' 를 유로 문자로 해석했지만 3 버전부터는 r'\u20ac' 를 6개의 문자로 해석을 합니다. 단, '\u20ac' 의 경우에는 여전히 유로 문자로 해석됩니다.

7) 2.3 버전에서 도입된 basestring 타입이 제거 됩니다. 대신 str를 사용하면 됩니다.
2to3 에서는 str로 변환을 합니다.
(basestring 은 2버전에서의 문자열이나 유니코드와 인스턴스 비교를 할 때 사용된 타입이라고 합니다.)

8) 텍스트 파일로 열리는 파일들은 (메모리에서)문자열과 (디스크에서)바이트 사이를 매치하는 인코딩을 사용합니다. 그리고 b 모드를 사용해서 열은 바이너리 파일은 메모리에서 바이트를 사용합니다. 즉, 파일을 잘못된 모드나 인코딩을 사용해서 열게 되면 I/O가 잘못된 데이터를 넘겨주는 것이 아니라 실패를 일으킵니다.
  또, 유닉스 사용자들도 올바른 모드를 사용해야 합니다.
(파이썬 책에 보니까 유닉스는 모든 파일을 2진(바이너리) 파일로 처리한다고 되어 있네요. 그런데 문자열과 바이너리를 매치 시켜서 사용한다고 하니까 무조건 모드를 적어주어야 하겠네요.)
  그리고 인코딩도 고려해야 하기 때문에 디폴트 인코딩에 의존하는 것은 자제해야 해야 합니다.
(언어 환경 변수를 설정할 수 있는 유닉스 계열의 경우 대부분(전부가 아닌) 디폴트 인코딩이 UTF-8 이라고 하는데, 그래도 이것에 의존해서는 안되겠죠.)
  그리고 인코딩을 지정해서 쓰기 때문에 더 이상 codecs 모듈에 있는 인코딩 스트림들은 사용할 필요가 없게 되었습니다.

9) 파일 이름들은 유니코드를 사용하게 됩니다. 그렇기 때문에 바이트 문자열을 사용하는 일부 플랫폼에서는 문제를 일으킬 수 있습니다. 대신 다른 방법으로, 파일 이름을 받아들이는 대부분의 API(open() 이나 os 모듈)들은 바이트 객체도 받아들입니다. 그리고 몇몇의 API들도 바이트 리턴값을 요구하는 방법을 가지고 있습니다.
  즉, os.listdir()은 인자가 바이트일 경우 바이트의 리스트를 리턴합니다. 참고로, os.listdir() 이 문자열을 리턴할 때 디코드될 수 없는 파일 이름들은 UnicodeError 예외를 일으키보다는 생략됩니다.

10) os.environ 이나 sys.argv 와 같은 일부 시스템 API의 경우, 바이트가 기본 인코딩으로 해석될 수 없을 때 문제를 일으킬 수 있습니다. 이 경우에는 언어 환경 변수를 설정한 뒤 재실행 하는 것이 가장 좋은 방법입니다.

11) PEP 3138
  비 아스키 코드 문자열이 repr 에 의해서 더 이상 escape 되지 않습니다. 그러나 출력될 수 없는 control character 와 code points 는 여전히 escape 됩니다.
  즉, 예전에는 repr('한글') 이라고 하게 되면 "'한글'" 이 아니라 "'\\xxx\\xxx\\xxx\\xxx'" 와 같이 표현 되었습니다. 그러나 이제는 "'한글'" 로 표현이 됩니다. 다만, '\n' 과 같은 문자는 여전히 "'\\n'" 로 표시가 됩니다.

12) PEP 3120, PEP 3131
  기본 소스 인코딩은 UTF-8 입니다. 그리고 비 아스키 문자열들도 변수로 허용이 됩니다. 다만, 표준 라이브러리들은 오직 아스키로만 남아 있습니다.
(However, the standard library remains ASCII-only with the exception of contributor names in comments.)

13) StringIO 와 cStringIO 모듈이 제거 되었습니다. 대신에, io 모듈을 임포트해서 io.StringIO 와 io.BytesIO 를 사용하면 됩니다.


6. Overview Of Syntax Changes

< 새로운 문법 >

1) 먼저, PEP 3107 내용입니다. 여기서는 함수 인자와 리턴 값의 주석을 다는 문법이 추가되었습니다. 사용하는 방법은

def foo(a: expression, b: expression = 5) -> expression:
    ...
와 같이 인자 오른쪽에 : expression 이라고 사용하면 되고, 리턴 값의 주석은 -> expression 과 같이 사용하면 됩니다.
(참고로 expression 은 의미 그대로 식이기 때문에 1+2 와 같이 파이썬 식을 넣으면 주석을 볼 때 식의 결과가 나옵니다.)

  그리고 위 주석들은 함수의 __annotations__라는 속성에 사전 형식으로 추가가 됩니다. 다만, 문법의 소개에서는 실행 중에 __annotations__ 속성을 사용해서 주석을 보는 경우 외에는 이러한 주석 방식은 의미가 없다고 합니다. 그리고 이러한 의도는 메타 클래스나 장식자, 프레임 워크를 통한 사용을 권장하는 것이라고 합니다.

2) 다음으로 PEP 3102 입니다. 함수의 인지가 키워드로만 사용할 수 있도록 하는 문법이 추가되었습니다. 예를 들어서
def f(a, b, c=key) :
    ...
가 있을 때, c가 오직 키워드로만 사용되게 하고 싶으면, c 인자 앞에 가변인수(*args)를 넣어주면 됩니다.
  예전 버전에서는 가변인수가 앞에 오게 되면 에러를 일으켰는데, 이러한 문법을 허용하고, 가변 인수 뒤에 오는 키워드 인자들은 오직 키워드만 받게 됩니다. 또, 가변인수를 받고 싶지 않을 경우에는 * 만 사용해서 가변인수 없이 오직 키워드 인자만 사용할 수 있습니다.
  사용의 예는
def f(a, b, *, c=key) :
   ...
입니다.

3) PEP 3104 내용입니다. 이 내용에서는 nonlocal 이라는 문(예약어)가 등장했습니다. 이름 그대로 이것은 글로벌 지역이 아닌 바깥 지역을 검색할 수 있게 합니다. 열혈강의 파이썬에 있는 예 중에서
>>> def bank_account1(initial_balance) :
    balance = initial_balance
    def deposit(amount) :
        balance = balance + amount
        return balance
    def withdraw(amount) :
        balance = balance - amount
        return balance
    return deposit, withdraw

>>> d, w = bank_account1(100)
>>> print(d(100))
와 같은 코드가 있을 때, balance = balance + amount 줄에서 에러가 발생하게 됩니다. balance 는 지역 내에 선언된 것도 아니고, 글로벌에 선언된 것도 아니기 때문에 중간에 있는 변수를 참조 할 수 없기 때문입니다. 그래서 책에서는 이것을 해결하기 위해 balance 를 리스트로 바꾸어서 해결을 했습니다. 그러나 nonlocal 의 추가로 이것을 간단하게 해결할 수 있게 되었습니다.
>>> def bank_account1(initial_balance) :
    balance = initial_balance
    def deposit(amount) :
        nonlocal balance
        balance = balance + amount
        return balance
    def withdraw(amount) :
        nonlocal balance
        balance = balance - amount
        return balance
    return deposit, withdraw

>>> d, w = bank_account1(100)
>>> print(d(100))
200
와 같이 nonlocal balance 를 중간에 삽입해주게 되면 함수 중간에 있는 balance 변수를 참조할 수 있게 됩니다.

4) PEP 3132 내용입니다. 이 내용에서는 반복 언팩킹 기능이 확장되었습니다. 함수에서 인자를 받을 때 여분의 인자는 *arg 와 같이 받는 형식처럼 언팩킹을 할 때 여분의 인자를 받을 수 있도록 바뀌었습니다. 예를 들어
a, *rest, b = range(5)
와 같이 입력을 해주면 시퀀스의 값을 3개로 나누어서 언팩킹을 해줍니다. a=0, rest=[1,2,3], b=4 로 대입이 되면서 언팩킹이 됩니다.

5) PEP 0274 내용입니다. 리스트 내장처럼 사전 내장이 추가되었습니다. 쓰는 방식은 아래와 같이 사용하면 됩니다.
{k: v for k, v in stuff}

  위 방식은 dict(stuff)와 같은 기능을 하는데, 위 방식이 더 유용하다고 PEP 내용에서 입증 되었다고 하네요.

6) set 자료형의 표현이 바뀌었습니다. 예전 버전에서는 set(['a', 'b'])와 같이 표현이 되었으나 3버전부터는 {'a', 'b'} 와 같이 표현이 됩니다. 다만, 주의 할 점은 {} 방식은 사전을 의미합니다. 빈 set 형을 사용하려면 set()으로 사용해야 합니다. 또, set 내장이 지원 됩니다. 즉,
{x for x in stuff}와 같이 사용할 수 있습니다. set(stuff)와 같은 기능이지만 더 유연하다고 합니다.

7) 8진법 표현 형식이 바뀌었습니다.
0o720와 같이 사용되며 0720의 표현은 사라졌습니다. 이 표현은 2.6에서 이미 적용되었습니다.

8) 2진법 형식이 생겼습니다. 0b1010과 같이 사용되며 이에 상응하는 내장 함수로 bin() 이 있습니다. 이 표현 역시 2.6에서 이미 적용 되었습니다.

9) 문자열에서 이미 말했 듯이 바이트 형식이 소개되었습니다. b'...' 나 B'...'로 표현이 되며, 이에 상응하는 함수로 bytes() 가 생겼습니다.


< 바뀐 문법 >

1) PEP 3109, PEP 3134 내용입니다. raise 문법이 새롭게 바뀌었습니다. 자세한 것은 아래에 설명 되어 있습니다.

2) as 와 with 가 새로운 예약어가 되었습니다.

3) True 와 False, None 이 예약어가 되었습니다.

4) PEP 3110. 예외 처리 문법에서 except exc, var 형식이 except exc as var 형태로 바뀌었습니다. 이 내용도 아래에 있습니다.

5) PEP 3115. 메타 클래스 문법이 바뀌었습니다.
class C:
    __metaclass__ = M
    ...
대신에
class C(metaclass = M) :
    ...
형식으로 바뀌었습니다. 따라서 더 이상 __metaclass__ 변수는 지원하지 않습니다.

6) 리스트 내장 문법에서 [... for var in item1, item2, ...] 이 더 이상 지원되지 않습니다. 대신에 [... for var in (item1, item2, ...)] 를 사용하면 됩니다. 그리고 리스트 내장은 다른 의미(semantics)를 가집니다. 리스트 구조 내부의 발생자 표현 문법과 더 가깝습니다. 또, surrounding scope 내의 loop control 변수가 더 이상 누수 되지 않습니다.

7) 생략(ellipsis) 구문이 점 표현 방식(...)으로 어디서든 사용될 수 있습니다. 예전 버전까지는 슬라이싱에서만 사용이 가능했습니다. 그리고 반드시 ... 써야 하며, . . . 방식은 안 됩니다.(예전까지는 됐습니다.)


< 제거된 문법 >

1) PEP 3113. 튜플 인자 언패킹 문법이 제거 되었습니다. 예를 들어서 def foo(a, (b, c)) : ... 를 더 이상 쓸 수 없고, 대신에 def foo(a, b_c) : b, c = b_c ... 와 같이 써야 합니다. 람다 함수에서도 마찬가지 입니다.

2)
backtick 기호(`)가 사라졌습니다. 대신에 repr 을 사용해야 합니다.

3) <> 기호가 사라졌습니다. 대신에 != 사용해야 합니다.

4) exec 키워드가 사라졌습니다. 대신 함수로 남아 있게 됩니다. 또한, exec()는 더 이상 stream 인자를 받지 않습니다. 예를 들어서 print 1 이 저장되어 있는 파이썬 파일을 변수 f 에 열었을 때, exec f 를 쓰게 되면 print 1 을 바로 읽고 실행이 되었으나 더 이상 이런 것이 불가능 하고, 대신에 exec(f.read()) 와 같이 사용해야 합니다.

5) 정수와 문자열에서 l, L, u, U 가 더 이상 지원되지 않습니다.

6) from (module) import * 문법은 모듈 레벨에서만 실행이 됩니다. 더 이상 함수 내에서는 불가능 합니다. 다만, from (module) import (name) 은 사용이 가능합니다.

7) 상대적 임포트 문법으로 from .[module] import name 만 가능합니다. 점(.) 으로 시작되지 않는 임포트 구문은 절대적 임포트로 해석됩니다.(2.5에서 상대적 임포트가 나왔을 때 점 없이도 상대적 임포트가 가능 했었습니다.)

8) Classic Class 가 사라졌습니다.


7. Changes Already Present In Python 2.6

이 부분의 내용들은 파이썬 2.6에도 이미 적용된 내용들입니다.

1) PEP 343 : The 'with' statement
  with 구문이 추가되었습니다. 더 이상 __future__ 에서 임포트 되지 않습니다. 자세한 사항은 파이썬 2.5에 기술된 내용과 같으므로
파이썬(Python) 2.5에서 새로운 점 를 참고 해주세요.

2) PEP 366 : Explicit Relative Imports From a Main Module
  파이썬을 -m 옵션을 추고 실행하면 스크립트로 모듈을 실행 한다고 합니다. 그런데 파이썬 패키지 내에 있는 모듈을 실행 시키면 상대적 임포트가 제대로 작동을 안한다고 합니다. 이 부분을 해결하기 위해 모듈에 __package__ 속성을 추가 했습니다. 이 속성이 나타날 때, 상대적 임포트는 __name__ 속성 대신에 이 속성의 값에 대해서 상대적이게 됩니다.

3) PEP 370 : Per-user site-packages Directory
  파이썬에서 개인 유저마다 site-packages 디렉토리를 가질 수 있도록 하였습니다. 그 전에는 site-packages 가 전체에서 쓸 수 있도록 되어 있었는데, 개인 마다도 쓸 수 있도록 소개가 되었습니다. site-packages 는 표준 라이브러리가 아닌 3rd 라이브러리들이 설치되는 경로입니다.
  우분투나 쿠분투에는 site-packages 가 아니라 dist-packages 로 되어 있습니다.
(이것 때문에 몇몇 프로그램에서는 오류가 발생한다는 얘기도 있네요. 그리고 site.py 를 보니까 파일 내부에 데비안 계열의 경우 dist-packages 에 저장이 된다고 쓰여져 있습니다.)

  디렉토리는 플랫폼에 따라서 경로가 다르게 나타납니다. Unix 와 Mac 에서는 ~/.local/ 이고, 윈도우즈에서는 %APPDATA%/Python 입니다. 이 내부에 unix, mac 은 lib/python2.6/site-packages 과 같이, 윈도우에서는 Python26/site-packages 와 같이 나타납니다.
  그리고 이 경로를 원하지 않을 경우 PYTHONUSERBASE 환경변수를 통해서 변경을 할 수 있고, 파이썬을 실행 할 때 -s 옵션을 주면 사용을 하지 않게 됩니다.
(-S 는 개인 유저 경로가 아닌 전체 경로에 있는 site-packages 를 사용하지 않을 때 사용합니다.)

  마지막으로 site.py 를 수정해서 site-packages 의 경로를 수정할 수도 있습니다. 자세한 사용 방법은 site.py를 보시면 됩니다.

4) PEP 371 : The multiprocessing Package
  multiprocessing 패키지가 추가 되었습니다. 패키지 이름 그대로 새로운 프로세스를 만들 수 있습니다. threading 모듈과 유사하다고 합니다. 자세한 것은 모듈을 직접 참고하세요.

5) PEP 3101 : Advanced String Formatting
  문자열 포맷이 향상되었습니다. str.format() 형식으로 사용이 가능합니다만 예전의 % 기호도 현재 지원하고 있지만 3.2 부터는 없애는 것으로 되어 있습니다. 그리고 2.6과 달리 3 에서는 문자열이 str 타입이므로 str 타입만 지원하고 bytes 타입은 지원하지 않습니다. 자세한 사항은 아래 글에 다가 정리를 해두었습니다.
http://blog.bluekyu.me/136

6) PEP 3105 : print As a Function
  위에서 자세히 설명한 부분입니다.

7) PEP 3110 : Exception-Handling Changes
  위에서 짧게 언급했고, 아래에서 더 자세히 소개합니다.

8) PEP 3112 : Byte Literals
  위에서 언급한 내용이고, 문서 상에는 C 와 어떻게 관련되어 있는지 나와 있습니다. 자세한 것은 직접 참조해주세요.

9) PEP 3116 : New I/O Library
  io 모듈이 파일 입출력의 새로운 표준이 되었습니다. sys.stdin, sys.stdout, sys.stderr 는 io.TextIOBase 의 인스턴스입니다. 내장 함수인 open() 도 io.open() 처럼 사용 되고 추가적인 키워드도 붙었습니다. 그리고 유효하지 않은 mode 인자일 경우 IOError 가 아니라 ValueError 를 발생 시킵니다. 더 자세한 것은 직접 참조해주세요.

10) PEP 3118 : Revised Buffer Protocol
  buffer() 내장 함수가 없어지고, 유사한 기능으로 memorryview() 가 내장으로 제공됩니다. 자세한 것은 직접 참조.

11) PEP 3119 : Abstract Base Classes
  객체 지향과 관련된 내용인 것 같은데, 잘 모르겠네요. 자세한 것은 직접 참조.

12) PEP 3127 : Integer Literal Support and Syntax
  정수와 관련해서 위에서 언급한 내용입니다.

13) PEP 3129 : Class Decorators
  클래스에서도 장식자를 메소드 장식자처럼 사용할 수 있게 되었습니다.

14) PEP 3141 : A Type Hierarchy for Numbers
  수에 대한 체계가 변경 되었습니다. 위에서 언급하지 못한 ABC 가 새롭게 바뀌면서 이 부분도 바뀐 것 같습니다. 가장 일반적인 ABC 는 Number 입니다. Complex 는 Number 의 서브클래스 입니다. Real 은 Complex 의 서브클래스 입니다. Rational 은 Real 의 서브클래스 입니다. Integer 는 Rational 의 서브클래스 입니다.
  그리고 분수와 관련된 모듈인 fractions 모듈이 추가 되었습니다. 더 자세한 것은 직접 참조하세요.


8. Library Changes

  라이브러리들이 많이 바뀌었습니다. 이 부분에 대해서는 너무 많아서 필요한 몇 개만 적겠습니다. 나머지는 PEP 3108을 참조해주세요.

1) md5 모듈과 sha 모듈이 hashlib 모듈로 대체 되었습니다.

2) cPickle 모듈 이름이 _pickle 로 바뀌었습니다.

3) StringIO 와 cStringIO 의 클래스가 io 모듈에 추가되었습니다.

4) 여러 그룹들이 재그룹화 되었습니다.

< dbm 패키지 >

Current Name Replacement Name
anydbm dbm.__init__
dbhash dbm.bsd
dbm dbm.ndbm
dumbdm dbm.dumb
gdbm dbm.gnu
whichdb dbm.__init__

< urllib 패키지 >
Current Name Replacement Name
urllib2 urllib.request, urllib.error
urlparse urllib.parse
urllib urllib.parse, urllib.request, urllib.error
robotparser urllib.robotparser

< tkinter 패키지 >
Current Name Replacement Name
Dialog tkinter.dialog
FileDialog tkinter.filedialog
FixTk tkinter._fix
ScrolledText tkinter.scrolledtext
SimpleDialog tkinter.simpledialog
Tix tkinter.tix
Tkconstants tkinter.constants
Tkdnd tkinter.dnd
Tkinter tkinter.__init__
tkColorChooser tkinter.colorchooser
tkCommonDialog tkinter.commondialog
tkFileDialog tkinter.filedialog
tkFont tkinter.font
tkMessageBox tkinter.messagebox
tkSimpleDialog tkinter.simpledialog
turtle tkinter.turtle

다음 내용은 PEP 3108에 없는 내용입니다.

1) sets 모듈이 제거 되었습니다. 내장 함수인 set 을 쓰면 됩니다.

2) sys 모듈이 정리되었습니다. sys.exitfunc(), sys.exc_clear(), sys.exc_type, sys.exc_value, sys.exc_traceback 이 제거되었습니다.

3) array.array 타입이 정리되었습니다. read(), write() 메소드가 없어지고, fromfile(), tofile() 을 사용하면 됩니다. 그리고 c 타입 코드가 없어지고 b 나 u 타입 코드를 사용하면 됩니다.

4) operator 모듈이 정리되었습니다. sequenceIncludes() 와 isCallable() 이 없어 졌습니다.

5) thread 모듈이 정리되었습니다. acquire_lock() 과 release_lock()이 없어지고, acquire()와 release() 를 사용하면 됩니다.

6) random 모듈이 정리되었습니다. jumpahead() 가 제거 되었습니다.

7) new 모듈이 없어졌습니다.

8) tmpfile 모듈을 위해 os.tmpnam(), os.tempnam(), os.tmpfile() 이 제거 되었습니다.

9) tokenize 모듈이 바이트와 작동하도록 바뀌었습니다. 주 입력 지점(Main Entry Point)는 generate_tokens 대신 tokenize.tokenize()로 바뀌었습니다.

10) string.letters와 string.lowercase, string.uppercase 가 사라졌습니다. 대신에, string.ascii_letters 등을 사용하면 됩니다.

11) 모듈 __builtin__ 이름이 builtins 로 바뀌었습니다. global 이름 공간에서 볼 수 있는 __builtins__ 변수는 바뀌지 않았습니다. builtin 을 수정하려면 __builtins__ 가 아닌 builtins 를 사용하면 됩니다.


9. Changes To Exceptions

예외 처리 부분이 많이 바뀌었습니다.

1) PEP 0352
  모든 예외는 BaseException 을 상속해야 합니다. 결과적으로 문자열 예외는 사라졌습니다.

2) 거의 모든 예외는 Exception 을 상속합니다. 즉, BaseException 은 SystemExit 나 KeyboardInterrup 와 같은 상위 레벨을 다루기 위한 예외 클래스의 기반입니다. 대부분의 예외들을 처리하기 위해서 제안하는 방식으로는 except Exception 을 사용하면 됩니다.

3) StandardError 는 제거 되었습니다.

4) 예외는 더 이상 시퀀스로 작동하지 않습니다. 대신에 args 속성을 사용하면 됩니다.
(열혈강의 파이썬 p. 481 의 예제에서 16번째 줄인 아래의 코드가 더 이상 작동이 안 된다는 의미 입니다.)
    print(a[0], a[0].__class__.__name__, id(a[0]))

5) PEP 3109
  raise Exception, args 대신에 raise Exception(args) 를 사용해야 합니다. 추가적으로 더 이상 traceback 명시할 수 없습니다. 만약, 이것을 하려면 __traceback__ 속성에 직접 할당 할 수 있습니다.

6) PEP 3110
  except Exception, variable 대신 except Exception as variable 을 사용해야 합니다. 만약, 두 가지 예외를 잡아내려면 튜플을 사용하면 됩니다. 그리고 except 블록이 사라질 때 variable 변수는 제거가 됩니다. 즉, 아래와 같은 코드는
except E as N :
    foo
다음과 같이 변환될 수 있습니다.
except E as N :
    try :
        foo
    finally :
        N = None
        del N
  따라서 예외 처리 구문 이후에도 값을 계속 참조하기를 원한다면 예외 처리에서 변수의 이름을 다르게 지정해주어야 합니다.

7) PEP 3134
  예외의 연쇄 처리 방식이 변경 되었습니다. 두 가지 방식이 있는데, 하나는 묵시적(implicit) 방식이고, 다른 하나는 명시적(explicit) 방식입니다. 묵시적 연쇄(2차 예외)는 except 나 finally 구문에서 발생하게 됩니다.
>>> try :
...     raise Exception('first')
... except :
...     raise Exception('second')
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
Exception: first

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
Exception: second
  위와 같이 try 구문에서 에러가 발생 했을 때, except 구문에서 처리를 하게 되는데, 2버전의 경우 except 에서 에러가 발생하면 try 에서 발생한 에러는 무시가 됩니다. 그러나 3버전부터는 위와 같이 첫번째에서 에러가 났고, 처리 도중에 두번째 에러가 발생 했다는 것을 알려줍니다. 이렇게 첫번째에서 발생한 에러가 소멸하는 것을 방지하기 위해 첫번째 에러는 두번째 에러 클래스의 __context__ 속성에 저장이 됩니다.

  다음으로 명시적 연쇄입니다. 명시적 예외는 raise EXCEPTION from CAUSE
의 구문에 의해서 발생이 되고, 이 구문은
exc = EXCEPTION
exc.__cause__ = CAUSE
raise exc

와 같은 의미를 가집니다.
즉, 명시적 예외가 발생하면 예외를 일으킨 CAUSE를 EXCEPTION 예외 클래스의 __cause__ 속성에 저장을 합니다. 예를 하나 들면
>>> try :
...     1/0
... except Exception as var :
...     raise Exception('1/0 is Error!') from var
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
Exception: 1/0 is Error!
  위와 같이 try 에서 예외가 발생 했는데, 그 예외를 except 에서 잡아내서 명시적으로 var 때문에 예외가 일어 났다는 것을 알려주고 있습니다. 즉, 묵시적 연쇄는 의미 그대로 파이썬 내부에서 2차 에러를 발생 시킨 1차 에러의 원인을 알려주게 됩니다. 그러나 명시적 연쇄는 프로그래머가 강제적으로 2차 에러와 함께 1차 에러의 원인을 알려주게 끔 합니다.
(참고적으로 IDLE 에서는 이러한 연쇄들이 나타나지 않습니다.)

8) PEP 3134
  예외 객체의 traceback 이 __traceback__ 속성 내에 저장이 됩니다. 예전에는 traceback 의 객체를 얻기 위해서는 sys.exc_traceback 이나 sys.exc_info()[2] 를 사용해야 했지만 이제는 간단하게 __traceback__ 속성만 참조를 하면 됩니다. 사용 방법은 아래와 같이 쓰면 됩니다.

def do_logged(file, work):
    try:
        work()
    except Exception, exc:
        write_exception(file, exc)
        raise exc

from traceback import format_tb

def write_exception(file, exc):
    ...
    type = exc.__class__
    message = str(exc)
    lines = format_tb(exc.__traceback__)
    file.write(... type ... message ... lines ...)
    ...
9) 윈도우즈에서 확장 모듈을 로드하는 데 실패 했을 때, 몇 가지 예외 메시지가 향상되었습니다.


10. Miscellaneous Other Changes

< Operators And Special Methods >

1) == 연산자가 NotImplemented 를 리턴하는 것을 제외하고, != 는 == 의 반대입니다.

2) 언바운드 메소드(unbound methods)의 개념이 사라졌습니다. 클래스 속성으로 메소드를 참조하게 되면 평범한 함수 객체를 얻게 됩니다.

3) __getslice__(), __setslice__(), __delslice__() 이 사라졌습니다. a[i:j] 문법은 a.__getitem__(slice(i, j)) 으로 전환 됩니다. 만약, 할당이나 삭제로 사용이 될 때는 __setitem__() 이나 __delitem__() 으로 바뀝니다.

4) PEP 3114. 반복자에서 사용되던 표준 next() 메소드의 이름이 __next__() 로 변경되었습니다. 즉, 다른 표준 메소드처럼 언더바를 사용합니다. 그리고 반복자를 호출하기 위해 a.next() 대신 내장함수인 next(a) 를 사용해서 반복자를 호출할 수 있습니다.

5) __oct__() 와 __hex__() 메소드가 제거되었습니다. 대신, oct() 와 hex() 메소드는 __index__() 메소드를 사용합니다.

6) __members__ 와 __methods__ 메소드가 제거되었습니다.

7) 함수 속성의 이름이던 func_X 가 __X__ 형식으로 변경되었습니다. 따라서, 이들의 이름이 함수 속성의 이름 공간에서 해제 되었습니다.

8) __nonzero__() 가 __bool__() 로 변경되었습니다.


< Builtins >

1) PEP 3135. 내장 함수인 super() 가 인자 없이 발생할 수 있게 되었습니다. 그리고 이것이 클래스 구문 내에 정의된 인스턴스 메소드 내에 있다고 했을 때, 올바른 클래스와 인스턴스가 자동적으로 선택되어집니다. 만약, 인자와 같이 쓰여지게 되면 예전의 super() 처럼 사용됩니다.

2) PEP 3111. raw_input() 이 input() 으로 이름이 변경되었습니다. 즉, input() 은 sys.stdin 으로 부터 라인을 읽고 새 라인(newline)을 없앤 후 값을 리턴합니다. 그리고 입력이 이르게(prematurely) 종료되었다면 EOFError 를 발생합니다.
  예전에 input() 함수를 사용하려면 eval(input()) 을 사용하면 됩니다.

3) __next__() 메소드를 호출하기 위해 내장 함수 next() 가 추가되었습니다.

4) intern() 이 sys.intern() 이 되었습니다.

5) apply() 가 제거 되어습니다. 즉, apply(f, args) 대신 f(*args) 로 사용하면 됩니다.

6) callable() 이 제거 되었습니다. callable(f) 대신 isinstance(f, collections.Callable) 를 사용하면 됩니다. operator.isCallable() 함수도 제거 되었습니다.

7) coerce() 가 제거되었습니다. classic 클래스가 사라졌기 때문에 이 함수는 더 이상 목적을 제공하지 않습니다.

8) execfile() 이 제거되었습니다. execfile(fn) 대신에 exec(open(fn).read()) 를 사용하면 됩니다.

9) file 타입이 제거 되었습니다. open() 을 사용하면 됩니다. io 모듈 내에 있는 open 이 리턴할 수 있는 몇 가지 다른 종료의 스트림(stream) 이 있습니다.

10) reduce() 가 제거되었습니다. functools.reduce() 를 사용하면 됩니다.
(문서 상에는 "그런데 그것이 정말로 필요하다면, 99%로 명확한 for 루프가 더 읽기 좋다"고 합니다.)

11) reload() 가 제거되었습니다. 대신, imp.reload() 를 사용하면 됩니다.

12) dict.has_key() 가 제거되었습니다. 대신, in 연산자를 사용하면 됩니다.


11. Build and C API Changes

문서 상에 이 부분이 시간 압박 때문에 매우 불완전하다고 합니다. 이 부분에 관해서는 직접 참고하시길 바랍니다.




이것으로 파이썬 3의 새로운 점에 관해서 글을 마칩니다. 만약, ABC 나 메타클래스와 같이 본문에서 설명이 부족한 부분에 대해서는 아래 두 글을 참고해 주세요.
http://www.ibm.com/developerworks/kr/library/l-python3-1/
http://www.ibm.com/developerworks/kr/library/l-python3-2/

마지막으로, 파이썬 3가 파이썬 2.5보다 속도가 10% 정도 떨어졌다고 합니다........... 가장 큰 원인이 작은 정수형(int) 이 사라지면서 발생한 문제라고 합니다. 나중에 많이 개선될 것이라고 생각합니다. ^^

댓글 3개:

  1. 안녕하세요.

    우선 좋은 글 감사합니다. ^^

    작성해 주신 "파이썬 3.0에서 새로운 점" 을

    점프 투 파이썬에 담고 싶습니다.



    점프 투 파이썬 - http://wikidocs.net/mybook/1



    점프 투 파이썬 독자는 제법 많은 편인데요

    작성해 주신 문서를 포함하면 큰 도움이 될 것 같습니다.



    가능한지 알려주시면 감사하겠습니다.

    박응용 (***@***.***)

    답글삭제
  2. @Bluekyu - 2010/06/29 13:45
    답글 보내 드렸습니다.

    그리고 메일을 가리느라 수정을 했더니 제가 등록한 것으로 되었네요. ^^;

    답글삭제
  3. 좋은 내용 감사합니다.

    잘 봤어요..

    따땃한 연말 보내시길..^^*

    답글삭제

크리에이티브 커먼즈 라이선스