Python

파이썬 3.0의 새로운 기능

저자:

위니센트 베르나(Vincent Bernat).

이 기사에서는 파이썬 3.0과 비교한 새로운 기능에 관해 설명합니다. 파이썬 3.0은 “Python 3000” 또는 “Py3K”로도 알려진 최초의 의도적으로 하위 호환성이 없는 Python 출시 버전입니다. 파이썬 3.0은 2008년 12월 3일에 배포되었습니다. 일반적인 릴리스보다 더 많은 변경 사항들이 있으며, 모든 파이썬 사용자에게 중요한 내용들도 포함하고 있습니다. 그럼에도 불구하고, 이러한 변경 사항들을 숙지하시면 파이썬이 그렇게 많이 바뀌지 않았다는 것을 알게 되실 겁니다. 대체로 우리는 잘 알려진 불편한 점들과 군더더기를 수정하고 오래된 잔재들(old cruft)을 제거하는 데 집중했습니다.

이 기사에서는 새로운 기능 전체에 대한 완벽한 사양을 제공하려 하기보다는, 편리하게 한눈에 볼 수 있도록 개요를 제시하고자 합니다. 자세한 내용을 확인하려면 파이썬 3.0에 대한 문서를 참조하거나, 본문에서 언급된 많은 PEP 문서들을 살펴보셔야 합니다. 특정 기능의 전체 구현 원리 및 설계 근거를 이해하고 싶으신 경우, PEP 문서가 일반 문서보다 더 자세한 정보를 제공하는 경우가 많습니다. 다만, PEP 문서들은 기능이 완전히 구현된 이후에는 일반적으로 최신 상태로 유지되지 않을 수 있다는 점에 유념해 주십시오.

시간적 제약으로 인해 이 문서는 충분히 완성도가 높지 않습니다. 항상 그렇듯이, 새 버전 출시 시점의 소스 배포본 내 Misc/NEWS 파일에는 변경된 모든 작은 요소들에 대한 풍부한 상세 정보가 담겨 있습니다.

일반적인 장애물들

이 섹션은 Python 2.5에 익숙한 경우 가장 걸릴 가능성이 높은 몇 가지 변경 사항들을 나열합니다.

리스트 대신 뷰와 이터레이터를 사용합니다

몇 가지 잘 알려진 API들이 더 이상 리스트를 반환하지 않습니다:

  • dict 메서드 dict.keys(), dict.items()dict.values() 는 이제 리스트가 아닌 “뷰”를 반환합니다. 예를 들어, 다음 코드는 더 이상 작동하지 않습니다: k = d.keys(); k.sort() 나 대신 k = sorted(d) 를 사용하십시오 (이것은 Python 2.5에서도 작동하며 효율성도 동일합니다).

  • 또한, dict.iterkeys(), dict.iteritems()dict.itervalues() 메서드는 더 이상 지원되지 않습니다.

  • map`과 :func:`filter`는 이터레이터를 반환합니다. 정말로 리스트가 필요하고 입력 시퀀스들이 모두 같은 길이를 가져야 한다면, 임시 조치는 :func:`map`을 :func:`list`로 감싸는 것입니다 (예: ``list(map(...))`()). 하지만 보다 좋은 해결책은 일반적으로 리스트 컴프리헨션(특히 원본 코드가 lambda`를 사용하는 경우)을 사용하거나, 아예 리스트가 필요하지 않도록 코드를 재작성하는 것입니다. 특히 함수 실행의 부수 효과를 위해 호출되는 :func:`map`은 까다로운데, 여기서 올바른 변환 방법은 일반적인 :keyword:`for 루프를 사용하는 것입니다 (리스트를 생성하는 것은 단순히 낭비일 뿐입니다).

    만약 입력 시퀀스가 길이가 일치하지 않는 경우, map`은 가장 짧은 시퀀스의 종료 지점에서 멈춥니다. Python 2.x의 :func:`map`과 완전히 호환되려면, 또한 시퀀스를 :func:`itertools.zip_longest`로 감싸야 합니다. 예: ``map(func, *sequences)`()list(map(func, itertools.zip_longest(*sequences))) 가 됩니다.

  • range`는 이제 이전의 :func:()!xrange`처럼 작동하지만, 임의의 크기 값을 처리할 수 있습니다. 후자는 더 이상 존재하지 않습니다.

  • :func:`zip`은 이제 이터레이터를 반환합니다.

순서 비교 (Ordering Comparisons)

Python 3.0에서 순서 비교 규칙을 단순화했습니다:

  • 순서 비교 연산자(<, <=, >=, >)는 피연산자가 의미 있는 자연적 순서를 갖지 않을 때 TypeError 예외를 발생시킵니다. 따라서 1 < '', 0 > None 또는 len <= len``과 같은 표현식은 이상 유효하지 않으며, 예를 들어 ``None < None``은 `False`를 반환하는 대신 :exc:`TypeError`을 발생시킵니다. 필연적으로는 이질적인 리스트를 정렬하는 것이 이상 의미가 없습니다. 모든 요소는 서로 비교 가능해야 합니다. 이것은 ``==!= 연산자에는 적용되지 않으며, 서로 비교할 수 없는 다른 유형의 객체들은 항상 서로 다릅니다.

  • :meth:`sorted`와 :meth:`list.sort`는 더 이상 비교 함수를 제공하는 cmp 인자를 받지 않습니다. 대신 key 인자를 사용하세요. 참고로, keyreverse 인자는 이제 “키워드 전용”입니다.

  • cmp() 함수는 사라진 것으로 간주해야 하며, __cmp__() 특수 메서드는 더 이상 지원되지 않습니다. 정렬에는 (만약 정말로 :func:()!cmp` 기능이 필요한 경우, (a > b) - (a < b) 표현식을 `cmp(a, b)`의 동등한 값으로 사용할 수 있습니다.)

정수형

  • PEP 237: 본질적으로 long`이 :class:`int`로 이름이 변경된 것입니다. 즉, 내장 정수형은 이름이 :class:`int 하나만 존재하지만, 이전의 long 타입과 대부분 유사하게 작동합니다.

  • PEP 238: 1/2 와 같은 표현식은 부동 소수점(float)을 반환합니다. 절삭 동작을 얻으려면 1//2 를 사용하세요. (후자 문법은 수년 동안 존재해 왔으며, 적어도 Python 2.2부터입니다.)

  • 정수 값에 대한 제한이 더 이상 없기 때문에 sys.maxint 상수가 제거되었습니다. 그러나, sys.maxsize`는 모든 실용적인 리스트나 문자열 인덱스보다 정수로 사용될 있습니다. 이는 구현의 "자연스러운" 정수 크기에 맞으며 일반적으로 같은 플랫폼의 이전 릴리스에서 :data:!sys.maxint`와 동일합니다 (동일한 빌드 옵션 가정 시).

  • 긴 정수의 repr() 은 더 이상 끝에 붙는 L 을 포함하지 않으므로, 조건을 상관없이 해당 문자를 제거하는 코드는 마지막 숫자를 잘라낼 것입니다. 대신 str() 을 사용하십시오.

  • 8진수 리터럴은 더 이상 0720 형식이 아닙니다. 대신 0o720 을 사용하세요.

유니코드 대 데이터, 혹은 문자열 대 8비트 (Text Vs. Data Instead Of Unicode Vs. 8-bit)

바이너리 데이터와 유니코드에 대해 알고 있다고 생각했던 모든 것이 변경되었습니다.

  • Python 3.0은 유니코드 문자열과 8비트 문자열 대신 텍스트*와 (바이너리) *데이터 개념을 사용합니다. 모든 텍스트는 유니코드이며, 다만 인코딩된 유니코드는 바이너리 데이터로 표현됩니다. 텍스트를 담는 데 사용되는 타입은 :class:`str`이고, 데이터를 담는 데 사용되는 타입은 :class:`bytes`입니다. 2.x 상황과의 가장 큰 차이점은 Python 3.0에서 텍스트와 데이터를 혼합하려는 모든 시도가 :exc:`TypeError`를 발생시키는 반면, Python 2.x에서 유니코드와 8비트 문자열을 혼합하는 것은 8비트 문자열에 우연히 7비트(ASCII) 바이트만 포함하고 있다면 작동했지만, 비-ASCII 값을 포함하면 :exc:`UnicodeDecodeError`가 발생했다는 것입니다. 이러한 값별 동작 방식 때문에 수년 동안 많은 슬픈 일이 있었습니다.

  • 이러한 철학의 변화에 따라 유니코드, 인코딩 또는 바이너리 데이터를 사용하는 코드 대부분을 변경해야 할 가능성이 높습니다. 이 변화는 더 좋습니다. 왜냐하면 2.x 환경에는 인코딩된 텍스트와 비인코딩된 텍스트를 혼합하는 것과 관련된 수많은 버그가 있었기 때문입니다. Python 2.x에서 대비하려면, 모든 비인코딩된 텍스트에는 unicode`를 사용하고 바이너리 또는 인코딩된 데이터에만 :class:`str`을 사용하기 시작하십시오. 그러면 ``2to3` 도구가 대부분의 작업을 대신해 줄 것입니다.

  • 유니코드 텍스트에는 더 이상 u"..." 리터럴를 사용할 수 없습니다. 대신, 바이너리 데이터에는 반드시 b"..." 리터럴를 사용해야 합니다.

  • strbytes 타입은 혼합할 수 없으므로, 항상 명시적으로 변환해야 합니다. str 에서 bytes 로 가려면 str.encode() 를 사용하고, bytes 에서 str 로 가려면 bytes.decode() 를 사용하십시오. 또한 각각에 대해 bytes(s, encoding=...)str(b, encoding=...) 를 사용할 수 있습니다.

  • str`와 마찬가지로, :class:`bytes 타입은 불변(immutable)입니다. 버퍼링된 바이너리 데이터를 저장하기 위한 별도의 가변 타입이 :class:`bytearray`가 있습니다. :class:`bytes`를 허용하는 거의 모든 API는 :class:`bytearray`도 허용합니다. 이 가변 API는 :class:`collections.MutableSequence <collections.abc.MutableSequence>`에 기반합니다.

  • Raw 문자열 리터럴의 모든 백슬래시는 리터럴로 해석됩니다. 이는 raw 문자열에서 '\U''\u' 이스케이프가 특별하게 취급되지 않음을 의미합니다. 예를 들어, r'\u20ac' 는 Python 3.0에서는 6개 문자의 문자열인 반면, 2.6 버전에서는 ur'\u20ac' 가 단일 “유로” 문자였습니다. (물론 이 변경은 raw 문자열 리터럴에만 영향을 미치며; 유로 문자는 Python 3.0에서 '\u20ac' 입니다.)

  • 내장 basestring 추상 타입이 제거되었습니다. 대신 str`를 사용하십시오. :class:`str`와 :class:`bytes 타입은 공유 기반 클래스를 가질 만큼 충분히 공통된 기능이 없습니다. 2to3 도구(아래 참조)가 :class:`!basestring`의 모든 발생을 :class:`str`로 대체합니다.

  • 텍스트 파일로 열린 파일(여전히 기본 모드인 open())은 인메모리 문자열과 디스크상의 바이트 간의 매핑을 항상 사용합니다. 바이너리 파일(모드 인자에 b``를 사용하여 열림)은 메모리에서 항상 바이트를 사용합니다. 이는 파일이 잘못된 모드나 인코딩으로 열리면, 부정확한 데이터가 조용히 생성되는 대신 I/O가 실패할 가능성이 높다는 것을 의미합니다. 또한 Unix 사용자조차도 파일을 올바른 모드(텍스트 또는 바이너리)를 지정해야 한다는 것을 의미합니다. 플랫폼 종속적인 기본 인코딩이 존재하는데, Unixy 플랫폼에서는 ``LANG 환경 변수로 설정할 수 있습니다(그리고 때로는 다른 플랫폼별 로케일 관련 환경 변수와 함께). 많은 경우에, 하지만 모두가 아닌 경우에, 시스템의 기본값은 UTF-8입니다. 이 기본값을 절대 신뢰해서는 안 됩니다. 순수한 ASCII 텍스트를 읽거나 쓰는 애플리케이션은 인코딩을 재정의할 방법을 가지는 것이 좋습니다. codecs 모듈에서 인코딩 인식 스트림을 사용할 필요성은 더 이상 없습니다.

  • sys.stdin, sys.stdoutsys.stderr`의 초기 값은 이제 유니코드 전용 텍스트 파일입니다(즉, :class:`io.TextIOBase 인스턴스입니다). 이러한 스트림으로 바이트 데이터를 읽거나 쓰려면, 해당 io.TextIOBase.buffer 속성을 사용해야 합니다.

  • 파일 이름은 API로 전달 및 반환될 때 (Unicode) 문자열입니다. 일부 플랫폼에서는 파일 이름이 임의의 바이트 문자열이기 때문에 이는 플랫폼별 문제를 야기할 수 있습니다. (반면, Windows에서는 파일 이름이 기본적으로 Unicode로 저장됩니다.) 해결책으로, 대부분의 API(예: open()os 모듈의 많은 함수)가 파일 이름을 받을 때 bytes 객체뿐만 아니라 문자열도 허용하며, 일부 API는 bytes 반환 값을 요청하는 방법이 있습니다. 따라서, 인수가 bytes 인스턴스인 경우 os.listdir`은 :class:`bytes() 인스턴스 목록을 반환하고, os.getcwdb`는 현재 작업 디렉터리를 :class:`bytes() 인스턴스로 반환합니다. 참고로, :func:`os.listdir`이 문자열 목록을 반환할 때 제대로 디코딩할 수 없는 파일 이름은 :exc:`UnicodeError`를 발생시키는 대신 생략됩니다.

  • os.environsys.argv`와 같은 일부 시스템 API도 시스템에서 제공하는 바이트가 기본 인코딩으로 해석되지 않을 문제를 일으킬 있습니다. ``LANG` 변수를 설정하고 프로그램을 다시 실행하는 것이 가장 좋은 방법일 것입니다.

  • PEP 3138: 문자열의 :func:`repr`은 더 이상 비-ASCII 문자를 이스케이프하지 않습니다. 하지만 여전히 제어 문자와 유니코드 표준에서 인쇄 불가능 상태인 코드 포인트는 이스케이프합니다.

  • PEP 3120: 기본 소스 인코딩이 이제 UTF-8입니다.

  • PEP 3131: 식별자에 비(非)ASCII 문자가 허용됩니다. (다만, 표준 라이브러리는 기여자 이름에 한해서 주석 처리 시 ASCII만 유지합니다.)

  • StringIOcStringIO 모듈은 사라졌습니다. 대신, io 모듈을 임포트하여 텍스트에는 io.StringIO, 데이터에는 :class:`io.BytesIO`를 사용하십시오.

  • :ref:`unicode-howto`에서 추가된 내용을 참고하십시오.

문법 변경 개요

본 섹션은 Python 3.0의 모든 문법적 변경 사항에 대한 간략한 개요를 제공합니다.

새 문법

  • PEP 3107: 함수 인자 및 반환 값 주석 처리. 이는 함수의 매개변수와 반환 값을 주석 처리하는 표준화된 방법을 제공합니다. 이러한 주석은 동작 시간에 __annotations__ 속성을 사용하여 검사될 수 있다는 점 외에는 어떠한 의미론적 바인딩도 없습니다. 의도는 메타클래스, 데코레이터 또는 프레임워크를 통해 실험을 장려하는 것입니다.

  • PEP 3102: 키워드 전용 인자. 매개변수 목록에서 *args 난 후에 오는 이름 지정 매개변수는 호출 시 반드시 키워드 문법을 사용하여 지정해야 합니다. 또한, 변수 길이의 인자 목록을 허용하지 않지만 키워드 전용 인자는 가지고 있음을 나타내기 위해 매개변수 목록에 빈 * 를 사용할 수도 있습니다.

  • 클래스 정의에서 상속 클래스 목록 뒤에는 키워드 인자가 허용됩니다. 이는 메타클래스를 지정하는 새로운 관습(다음 섹션 참조)에 의해 사용되지만, 메타클래스가 지원하는 한 다른 목적으로도 사용할 수 있습니다.

  • PEP 3104: nonlocal 문. nonlocal x 를 사용하면 이제 외부에 있는 (하지만 전역이 아닌) 변수에 직접 할당할 수 있습니다. nonlocal 은 새로운 예약어입니다.

  • PEP 3132: 확장 이터러블 언 패킹. 이제 a, b, *rest = some\_sequence``와 같은 구문을 작성할 있습니다. 심지어 ``*rest, a = stuff``도 가능합니다. ``rest 객체는 항상 (비어 있을 수도 있는) 리스트이며, 오른쪽에 오는 값은 임의의 이터러블이 될 수 있습니다. 예시:

    (a, *rest, b) = range(5)
    

    이것은 a0 을, b4 를, 그리고 rest[1, 2, 3] 을 설정합니다.

  • 딕셔너리 컴프리헨션: {k: v for k, v in stuff}dict(stuff) 와 동일한 의미를 갖지만 더 유연합니다. (이는 PEP 274 가 승인된 것입니다. :-)

  • 집합 리터럴, 예: {1, 2}. {} 는 빈 딕셔너리이니, 빈 집합을 위해서는 set() 를 사용하십시오. 집합 컴프리헨션 또한 지원됩니다. 예: {x for x in stuff}set(stuff) 와 동일한 의미를 갖지만 더 유연합니다.

  • 새로운 8진수 리터럴, 예: 0o720 (이미 2.6에 존재). 이전의 8진수 리터럴(0720)은 사라졌습니다.

  • 새로운 2진수 리터럴, 예: 0b1010 (이미 2.6에 존재), 그리고 이와 상응하는 새로운 내장 함수 :func:`bin`이 있습니다.

  • 바이트 리터럴은 선행 b 또는 B 로 도입되었으며, 이에 대응하는 새로운 내장 함수 bytes() 가 있습니다.

변경된 문법

  • PEP 3109PEP 3134: 새로운 raise 문법: raise [expr [from expr]]. 자세한 내용은 아래를 참조하십시오.

  • :keyword:`!as`와 :keyword:`with`는 이제 예약어입니다. (실제로는 2.6부터 그러했습니다.)

  • True, False, 그리고 None 은 예약어입니다. (이미 2.6에서 None 에 대한 제한이 부분적으로 적용되었습니다.)

  • except exc, varexcept exc as var 로 변경하였습니다. 자세한 내용은 PEP 3110 을 참조하십시오.

  • PEP 3115: 새로운 메타 클래스 문법. 이전에는:

    class C:
        __metaclass__ = M
        ...
    

    이제 다음과 같이 사용해야 합니다:

    class C(metaclass=M):
        ...
    

    모듈 전역 __metaclass__ 변수는 더 이상 지원되지 않습니다. (이것은 모든 클래스를 :class:`object`로부터 상속받지 않고 새 스타일의 클래스로 기본 설정하기 위한 임시방편이었습니다.)

  • 리스트 컴프리헨션은 더 이상 문법적 형식인 [... for var in item1, item2, ...]`를 지원하지 않습니다. 대신 :samp:`[... for var in (item1, item2, ...)]`을 사용하십시오. 또한 리스트 컴프리헨션은 다른 의미론적 특징이 있다는 점에 유의해야 합니다. 이는 기본적으로 :func:`list 생성자 내부의 제너레이터 표현식에 가까운 구문적 설탕이며, 특히 루프 제어 변수들이 주변 스코프로 누설되지 않습니다.

  • 줄임표 (...)는 어디서든 원자적 표현식으로 사용될 수 있습니다. (이전에는 슬라이스에서만 허용되었습니다.) 또한, 지금은 반드시 ... 로 표기해야 합니다. (이전에는 문법상의 단순한 사고로 인해 . . . 로도 표기할 수 있었습니다.)

제거된 구문(Syntax)

  • PEP 3113: 튜플 매개변수 언패킹이 제거되었습니다. 더 이상 def foo(a, (b_, c)): ... 와 같이 작성할 수 없습니다. 대신 def foo(a, b_c): b_, c = b_c 를 사용하십시오.

  • 백틱(``)이 제거되었습니다 (대신 :func:`repr`을 사용합니다).

  • <> 가 제거되었습니다 (대신 != 를 사용하십시오).

  • 제거된 키워드: exec() 는 더 이상 키워드가 아니며, 함수로 남아 있습니다. (다행히도 함수 구문은 2.x에서도 허용되었습니다.) 또한, exec() 가 스트림 인자를 받지 않는다는 점도 참고하십시오. exec(f) 대신 exec(f.read()) 를 사용할 수 있습니다.

  • 정수 리터럴은 더 이상 접미사 l 또는 L 을 지원하지 않습니다.

  • 문자열 리터럴은 더 이상 선행하는 u 또는 U 를 지원하지 않습니다.

  • from 모듈 import * 구문은 모듈 수준에서만 허용되며, 함수 내부에서는 더 이상 허용되지 않습니다.

  • 상대 임포트에 대한 유일하게 허용되는 문법은 from .[module] import name`입니다. `.``로 시작하지 않는 모든 import 형식은 절대 임포트로 해석됩니다. (PEP 328)

  • 클래식이 사라졌습니다.

Python 2.6에 이미 존재하는 변화

많은 사용자가 Python 2.5에서 Python 3.0으로 바로 넘어가리라고 가정하므로, 이 섹션은 원래 Python 3.0용으로 설계되었지만 Python 2.6에 백포트된 새로운 기능들을 독자에게 상기시켜 드립니다. 더 자세한 설명은 :ref:`whats-new-in-2.6`의 해당 섹션을 참조하십시오.

라이브러리 변경 사항

시간 제약으로 인해 이 문서는 표준 라이브러리의 매우 광범위한 변경 사항을 포괄적으로 다루지는 못합니다. :pep:`3108`가 라이브러리 주요 변경 사항에 대한 참고 자료입니다. 여기 간략한 검토 내용이 있습니다:

  • 많은 오래된 모듈들이 제거되었습니다. 일부는 gopherlib (더 이상 사용되지 않음) 및 md5 ( hashlib`으로 대체됨)와 같이 이미 :pep:`4`에서 사용 기한이 만료되었습니다. 다른 모듈들은 Irix, BeOS, Mac OS 9 다양한 플랫폼에 대한 지원 제거로 인해 삭제되었습니다 (참고: :pep:`11). 또한 일부 모듈은 사용 부족이나 더 나은 대체재가 존재하기 때문에 Python 3.0에서 제거 대상으로 선정되었습니다. 전체 목록은 :pep:`3108`을 참조하십시오.

  • bsddb3 패키지는 핵심 표준 라이브러리에 존재하는 것이 테스트 불안정성 및 Berkeley DB의 릴리스 일정으로 인해 코어 개발자들에게 특히 큰 부담이 되어 제거되었습니다. 하지만 이 패키지는 살아 있으며, 외부적으로 https://www.jcea.es/programacion/pybsddb.htm에서 유지 관리되고 있습니다.

  • 일부 모듈은 기존 이름이 :pep:`8`을 준수하지 않았거나 기타 여러 가지 이유로 이름이 변경되었습니다. 목록은 다음과 같습니다:

    기존 이름

    새 이름

    _winreg

    winreg

    ConfigParser 객체입니다.

    configparser

    copy_reg

    copyreg

    Queue 객체입니다.

    queue

    SocketServer

    socketserver

    markupbase

    _markupbase

    repr

    reprlib

    test.test_support

    test.support

  • Python 2.x에서 일반적인 패턴은 모듈의 하나의 버전이 순수 Python으로 구현되고, 선택적 가속화된 버전이 C 확장을 통해 구현되는 것입니다. 예를 들어, pickle`과 :mod:!cPickle`가 그러합니다. 이는 각 사용자가 이 모듈의 가속화된 버전을 가져와야 하며, 순수 Python 버전으로 폴백(fall back)해야 하는 부담을 안깁니다. Python 3.0에서는 가속화된 버전이 순수 Python 버전의 구현 세부 사항으로 간주됩니다. 사용자는 항상 표준 버전을 임포트해야 합니다. 이 버전은 가속화된 버전을 임포트할 것을 시도하고 실패하면 순수 Python 버전으로 폴백합니다. pickle / cPickle 쌍은 이러한 처리 과정을 거쳤습니다. profile 모듈은 3.1의 목록에 있습니다. 그리고 StringIO 모듈은 io 모듈 내 클래스로 변경되었습니다.

  • 일부 관련 모듈들은 패키지로 그룹화되었으며 일반적으로 서브모듈 이름들이 간소화되었습니다. 결과로 생성된 새로운 패키지들은 다음과 같습니다:

    • dbm (anydbm, dbhash, dbm, dumbdbm, gdbm, whichdb).

    • html (HTMLParser, htmlentitydefs).

    • http (httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib).

    • tkinter ( :mod:`turtle`를 제외한 모든 Tkinter 관련 모듈). :mod:`turtle`의 대상 사용자들은 :mod:`tkinter`에 크게 신경 쓰지 않습니다. 또한 Python 2.6 버전부터는 :mod:`turtle`의 기능이 대폭 향상되었음을 유의하십시오.

    • urllib (urllib, urllib2, urlparse, robotparse).

    • xmlrpc (xmlrpclib, DocXMLRPCServer, SimpleXMLRPCServer).

:pep:`3108`에서 다루지 않은 표준 라이브러리 모듈의 기타 변경 사항들:

  • sets`가 폐지되었습니다. 내장된 :func:`set 클래스를 사용하십시오.

  • sys 모듈 정리: sys.exitfunc(), sys.exc_clear(), sys.exc_type, sys.exc_value, sys.exc_traceback`이 제거되었습니다. (참고로, :data:`sys.last_type 등은 남아 있습니다.)

  • array.array 타입 정리: read()write() 메서드가 사라졌습니다. 대신 fromfile()tofile() 을 사용하십시오. 또한 배열의 'c' 타입 코드는 제거되었으므로 바이트는 'b' 또는 유니코드 문자는 'u' 를 사용하십시오.

  • operator 모듈 정리: sequenceIncludes`와 :func:()!isCallable`이 제거되었습니다.

  • thread 모듈 정리: acquire_lock`과 :func:()!release_lock`이 사라졌습니다. 대신 :meth:`~threading.Lock.acquire`와 :meth:`~threading.Lock.release`를 사용하십시오.

  • random 모듈 정리: jumpahead() API가 제거되었습니다.

  • new 모듈이 사라졌습니다.

  • 함수 os.tmpnam(), os.tempnam(), 그리고 os.tmpfile`은 :mod:`tempfile() 모듈을 대신하여 제거되었습니다.

  • tokenize 모듈이 바이트와 작동하도록 변경되었습니다. 주요 진입점은 이제 generate_tokens 대신 :func:`tokenize.tokenize`입니다.

  • string.letters 및 그 친구들 (string.lowercasestring.uppercase)는 제거되었습니다. 대신 string.ascii_letters 등을 사용하십시오. (제거 이유는 :data:`!string.letters`와 같은 친구들이 지역화별 동작을 했고, 이는 이렇게 매력적으로 이름 붙여진 전역 “상수”의 경우 나쁜 아이디어였기 때문입니다.)

  • 모듈 __builtin__`가 :mod:`builtins`로 이름이 변경되었습니다 (언더스코어를 제거하고 's'를 추가했습니다). 대부분의 전역 네임스페이스에서 발견되는 :data:!__builtins__` 변수는 변경되지 않았습니다. 내장 기능을 수정하려면 :data:`!__builtins__`가 아닌 :mod:`builtins`를 사용하십시오!

PEP 3101: 문자열 포매팅의 새로운 접근 방식

  • 새로운 내장 문자열 포매팅 연산 체계가 % 문자열 포매팅 연산자를 대체합니다. (하지만, % 연산자는 여전히 지원되며; Python 3.1에서 사용 중단되고 나중 어느 시점에 언어에서 제거될 예정입니다.) 전체 내용은 :pep:`3101`을 참조하십시오.

예외의 변경 사항

예외를 발생시키고 포착하는 API가 정리되었으며 강력한 새 기능이 추가되었습니다:

  • PEP 352: 모든 예외는 BaseException 으로부터 상속되어야 합니다 (직접 또는 간접적으로). 이것은 예외 계층 구조의 루트입니다. 이는 권장 사항으로서 새로운 것이 아니라, BaseException 으로부터 상속해야 하는 요구사항 이 새로운 것입니다. (Python 2.6에서는 여전히 클래식 클래스를 발생시키는 것이 허용되었으며, 무엇을 포착할지에 제한을 두지 않았습니다.) 그 결과, 문자열 예외는 마침내 진정으로 완전히 사장되었습니다.

  • 거의 모든 예외는 실제로 Exception`으로부터 파생되어야 합니다. :exc:`BaseException`은 :exc:`SystemExit`나 :exc:`KeyboardInterrupt`와 같이 최상위 레벨에서만 처리해야 하는 예외를 위한 기본 클래스로만 사용해야 합니다. 후반 카테고리를 제외한 모든 예외를 처리하는 권장 관용구는 :keyword:`except :exc:`Exception`을 사용하는 것입니다.

  • :exc:`!StandardError`가 제거되었습니다.

  • 예외는 더 이상 시퀀스로 동작하지 않습니다. 대신 args 어트리뷰트를 사용하십시오.

  • PEP 3109: 예외 발생. 이제 raise Exception(args)`를 :samp:`raise Exception, args 대신 사용해야 합니다. 또한, 더 이상 트레이스백을 명시적으로 지정할 수 없으므로; 대신 반드시 해야 한다면, __traceback__ 어트리뷰트에 직접 할당할 수 있습니다 (아래 참조).

  • PEP 3110: 예외 포착. 이제 except SomeException as variableexcept SomeException, variable 대신 사용해야 합니다. 게다가, 변수except 블록을 떠날 때 명시적으로 삭제됩니다.

  • PEP 3134: 예외 체이닝. 두 가지 케이스가 있습니다. 암묵적 체이닝과 명시적 체이닝입니다. 암묵적 체이닝은 except 또는 finally 처리기 블록에서 예외가 발생할 때 발생합니다. 이는 보통 핸들러 블록의 버그로 인해 발생하며, 우리는 이를 보조 예외라고 부릅니다. 이 경우, 원래 예외(처리 중이던)는 보조 예외의 __context__ 어트리뷰트로 저장됩니다. 명시적 체이닝은 다음 구문으로 호출됩니다:

    raise SecondaryException() from primary_exception
    

    (여기서 primary_exception 은 예외 객체를 생성하는 모든 표현식이며, 아마도 이전에 포착되었던 예외일 것입니다). 이 경우, 기본 예외는 보조 예외의 __cause__ 어트리뷰트에 저장됩니다. 처리되지 않은 예외가 발생할 때 인쇄되는 트레이스백은 __cause____context__ 어트리뷰트 체인을 따라 이동하며, 체인의 각 구성 요소에 대해 별도의 트레이스백을 출력하고 기본 예외는 상단에 배치됩니다. (Java 사용자는 이 동작을 인지할 수 있습니다.)

  • PEP 3134: 이제 예외 객체는 자신의 트레이스백을 __traceback__ 어트리뷰트로 저장합니다. 이는 예외 객체가 이제 예외에 관한 모든 정보를 포함하며, :func:`sys.exc_info`를 사용할 이유가 줄어들었음을 의미합니다 (비록 후자가 제거된 것은 아니지만).

  • 확장 모듈을 로드하지 못할 때 발생하는 몇 가지 예외 메시지가 개선되었습니다. 예를 들어, error code 193 은 이제 %1는 유효한 Win32 애플리케이션이 아닙니다 가 됩니다. 문자열은 이제 비영어 로케일과 처리합니다.

기타 변경 사항

연산자와 특수 메서드

  • != 는 더 이상 == 의 반환 값을 반환하지 않습니다. 단, ==NotImplemented 를 반환할 경우에는 예외입니다.

  • “연결되지 않은 메서드(unbound methods)”라는 개념이 언어에서 제거되었습니다. 클래스 속성으로 메서드를 참조할 때, 이제는 일반 함수 객체를 얻게 됩니다.

  • __getslice__(), __setslice__()__delslice__`가 제거되었습니다. 구문 ``a[i:j]``는 이제 ``a.__getitem__(slice(i, j))``로 แปลง되며 (또는 할당이나 삭제 대상의 경우 각각 :meth:`~object.__setitem__() 또는 :meth:`~object.__delitem__`를 사용합니다).

  • PEP 3114: 표준 next() 메서드가 :meth:`~iterator.__next__`로 이름이 변경되었습니다.

  • 특별 메서드인 __oct__()__hex__`가 제거되었으며, 이제 :func:`oct() 및 :func:`hex`는 인자를 정수로 변환하기 위해 :meth:`~object.__index__`를 사용합니다.

  • __members__ 및 :attr:`!__methods__`에 대한 지원이 제거되었습니다.

  • 속성 이름이 지정된 함수 속성 func_X``는 이제 네임스페이스에서 사용자 정의 속성을 확보하기 위해 :attr:!__X__` 형식으로 이름을 변경했습니다. 즉, func_closure: __closure__: func_code: __code__: func_defaults: __defaults__: func_dict: __dict__: func_doc: __doc__: func_globals: __globals__: func_name: :attr:`~function.__name__`로 각각 이름이 변경되었습니다.

  • :meth:`!__nonzero__`는 이제 :meth:`~object.__bool__`입니다.

내장 기능

  • PEP 3135: 새로운 super`가 추가되었습니다. 이제 인자 없이 :func:`super`를 호출할 있으며 (이것이 `:keyword:class() 문 내부에서 정의된 일반 인스턴스 메서드라고 가정하면), 올바른 클래스와 인스턴스가 자동으로 선택됩니다. 인자 사용 시, :func:`super`의 동작은 변경되지 않습니다.

  • PEP 3111: raw_input()input() 으로 이름이 변경되었습니다. 즉, 새로운 input() 함수는 sys.stdin 에서 한 줄을 읽고 끝에 있는 개행 문자를 제거하여 반환합니다. 입력이 조기에 종료되면 EOFError 를 발생시킵니다. 이전의 input() 동작을 얻으려면 eval(input()) 를 사용하십시오.

  • 객체에 대해 __next__() 메서드를 호출하는 새로운 내장 함수 :func:`next`가 추가되었습니다.

  • round() 함수의 반올림 전략과 반환 타입이 변경되었습니다. 정확히 중간인 경우는 이제 0에서 떨어진 방향이 아닌 가장 가까운 짝수로 반올림됩니다. (예를 들어, round(2.5) 는 더 이상 3 이 아니라 2 를 반환합니다.) round(x[, n]) 은 항상 float을 반환하는 대신 이제 x.__round__([n]) 으로 위임됩니다. 일반적으로 단일 인자와 함께 호출될 때는 정수를, 두 개의 인자 값을 가진 x와 동일한 타입의 값과 함께 호출될 때는 해당 값과 같은 타입을 반환합니다.

  • :func:`!intern`이 :func:`sys.intern`으로 이동되었습니다.

  • 제거됨: apply(). apply(f, args) 대신 f(*args) 를 사용하십시오.

  • callable() 이 제거되었습니다. callable(f) 대신 isinstance(f, collections.Callable) 를 사용할 수 있습니다. operator.isCallable() 함수도 사라졌습니다.

  • :func:`!coerce`가 제거되었습니다. 클래식 클래스가 사라짐에 따라 이 함수는 더 이상 의미가 없습니다.

  • execfile() 이 제거되었습니다. execfile(fn) 대신 open(fn).read() 을 사용하는 exec() 를 사용하십시오.

  • file 타입이 제거되었습니다. open`을 사용하십시오. 이제 :mod:`io() 모듈에는 여러 가지 다른 종류의 스트림이 존재합니다.

  • reduce`가 제거되었습니다. 필요하다면 :func:`functools.reduce`를 사용하십시오. 하지만 99퍼센트의 경우 명시적인 :keyword:`for() 루프가 더 읽기 쉽습니다.

  • reload`가 제거되었습니다. :func:()!imp.reload`를 사용하십시오.

  • 제거됨: dict.has_key`() – 대신 in 연산자를 사용하십시오.

빌드 및 C API 변경사항

시간 제약으로 인해, C API에 대한 매우 불완전한 변경 목록입니다.

  • Mac OS 9, BeOS, RISCOS, Irix 및 Tru64를 포함하여 여러 플랫폼에 대한 지원이 제외되었습니다.

  • PEP 3118: 새로운 버퍼 API.

  • PEP 3121: 확장 모듈 초기화 및 최종화.

  • PEP 3123: :c:macro:`PyObject_HEAD`를 표준 C에 맞추기.

  • 제한된 실행을 위한 C API 지원이 더 이상 제공되지 않습니다.

  • PyNumber_Coerce(), PyNumber_CoerceEx(), PyMember_Get(), 및 PyMember_Set() C API가 제거되었습니다.

  • 새로운 C API :c:func:!PyImport_ImportModuleNoBlock``는 `:c:func:`PyImport_ImportModule``와 유사하게 작동하지만, 임포트 잠금(import lock)에서 대기하지 않고 오류를 반환합니다.

  • 부울 변환 C 레벨 슬롯과 메서드의 이름이 변경되었습니다: nb_nonzero 는 이제 nb_bool 입니다.

  • C API에서 METH_OLDARGSWITH_CYCLE_GC 가 제거되었습니다.

성능

3.0 일반화의 최종 결과는 Python 3.0이 pystone 벤치마크에서 Python 2.5보다 약 10% 느리게 실행된다는 것입니다. 가장 큰 원인은 아마도 작은 정수에 대한 특별 처리(special-casing)가 제거된 것일 가능성이 높습니다. 개선의 여지는 있지만, 이는 3.0이 출시된 후에 발생할 것입니다!

Python 3.0으로 이식하기

기존의 Python 2.5 또는 2.6 소스 코드를 Python 3.0으로 포팅하는 가장 좋은 전략은 다음과 같습니다:

  1. (사전 조건:) 우수한 테스트 커버리지로 시작하세요.

  2. Python 2.6으로 포팅합니다. 이는 Python 2.x에서 Python 2.(x+1)로의 평균적인 포팅 작업보다 많지 않을 것입니다. 모든 테스트가 통과하는지 확인하세요.

  3. (2.6을 계속 사용하는 경우:) -3` 명령줄 스위치를 켜세요. 이렇게 하면 3.0에서 제거되거나 변경될 기능에 대한 경고가 활성화됩니다. 테스트 스위트를 다시 실행하고, 더 이상 경고가 남지 않고 모든 테스트가 여전히 통과할 때까지 경고를 받는 코드를 수정하세요.

  4. 2to3 소스-소스 변환 도구를 소스 코드 트리 전체에 실행합니다. 번역 결과를 Python 3.0에서 실행하세요. 모든 테스트가 다시 통과할 때까지 남아 있는 모든 이슈를 수동으로 수정하여 문제를 해결하십시오.

Python 2.6과 3.0 모두에서 변경 없이 실행되는 소스 코드를 작성하려 시도하는 것은 권장되지 않습니다. 예를 들어 print 구문이나 메타클래스를 피해야 하는 매우 복잡하게 뒤틀린 코딩 스타일을 사용해야 할 것입니다. 만약 Python 2.6과 Python 3.0 모두를 지원해야 하는 라이브러리를 유지 관리하고 있다면, 3.0 버전의 소스 코드를 수정하기보다는 위의 단계 3을 수정하여 2.6 버전의 소스 코드를 편집한 후 2to3 변환기를 다시 실행하는 것이 가장 좋은 접근 방식입니다.

Python 3.0으로 C 확장을 포팅하려면 :ref:`cporting-howto`를 참조하십시오.

분실물 보관소