Python

Python 2.5의 새로운 기능

저자:

A.M. Kuchling

이 문서는 Python 2.5의 새로운 기능을 설명합니다. Python 2.5의 최종 릴리스는 2006년 8월로 예정되어 있으며, :pep:`356`에 계획된 릴리스 일정이 설명되어 있습니다. Python 2.5는 2006년 9월 19일에 출시되었습니다.

Python 2.5의 변경 사항은 언어적 개선과 라이브러리적 개선이 흥미롭게 혼합되어 있습니다. 광범위하게 유용한 여러 패키지가 추가되었기 때문에, 저는 이 라이브러리 향상에 사용자 커뮤니티가 더 중요하다고 생각합니다. 새 모듈에는 XML 처리를 위한 ElementTree(:mod:`xml.etree``), SQLite 데이터베이스 모듈(:mod:`sqlite``), C 함수 호출을 위한 :mod:`ctypes`` 모듈이 포함됩니다.

[msgid] The language changes are of middling significance. Some pleasant new features were added, but most of them aren’t features that you’ll use every day. Conditional expressions were finally added to the language using a novel syntax; see section PEP 308: 조건 표현식. The new ‘with’ statement will make writing cleanup code easier (section PEP 343: ‘with’ 문). Values can now be passed into generators (section PEP 342: 새로운 제너레이터 기능들). Imports are now visible as either absolute or relative (section PEP 328: 절대 및 상대 임포트). Some corner cases of exception handling are handled better (section PEP 341: try/except/finally 통합). All these improvements are worthwhile, but they’re improvements to one specific language feature or another; none of them are broad modifications to Python’s semantics.

언어 및 라이브러리 추가와 더불어, 전체 소스 트리에 걸쳐 다른 개선 사항과 버그 수정이 이루어졌습니다. SVN 변경 로그를 검색한 결과, Python 2.4에서 2.5 사이에 패치가 353개 적용되었고 버그가 458개 수정된 것으로 나타났습니다. (두 수치 모두 과소평가일 가능성이 높습니다.)

이 설명서는 새로운 기능에 대한 완전한 명세를 제공하려고 작성된 것이 아니며, 대신 유용한 예제를 사용해 간략하게 변화를 소개합니다. 모든 자세한 내용은 https://docs.python.org 에서 Python 2.5의 문서를 항상 참조해야 합니다. 전체 구현과 설계 근거를 이해하려면 특정 새 기능에 대한 PEP를 참조하십시오.

이 문서에 대한 댓글, 제안 및 오류 보고는 환영합니다. 저자에게 이메일을 보내거나 Python 버그 추적기에서 버그를 여십시오.

PEP 308: 조건 표현식

오랫동안 사람들은 조건에 따라 값 A 또는 값 B를 반환하는 표현식을 작성하는 방법을 요청해 왔습니다. 조건 표현식은 다음을 실행하는 것과 동일한 효과를 가진 단일 할당 문장을 작성할 수 있게 해줍니다:

if condition:
    x = true_value
else:
    x = false_value

python-dev와 comp.lang.python 양쪽에서 구문에 대한 끝없는 지루한 토론이 있었습니다. 투표에서는 대다수 유권자가 어떤 형태이든 조건 표현식을 원한다는 결과가 나왔지만, 명확한 다수가 선호하는 문법은 없었습니다. 후보에는 C의 cond ? true_v : false_v, if cond then true_v else false_v 그리고 다른 16가지 변형들이 포함되었습니다.

가이도 반 로섬은 결국 놀라운 문법을 선택했습니다:

x = true_value if condition else false_value

평가 순서는 여전히 기존의 부울 표현식과 같이 지연됩니다. 따라서 평가 순서가 다소 뒤섞입니다. 중간에 있는 condition 표현식이 먼저 평가되고, condition이 참일 경우에만 true_value 표현식이 평가됩니다. 마찬가지로, false_value 표현식은 condition이 거짓일 때만 평가됩니다.

이 문법은 낯설고 역행하는 것처럼 보일 수 있습니다. 왜 조건이 C의 c ? x : y 처럼 표현식의 중간 에 오며 앞에 오지 않는 것일까요? 이 결정은 표준 라이브러리의 모듈에 새로운 문법을 적용해 보고 그 결과 코드가 어떻게 보이는지를 확인하여 이루어졌습니다. 조건식이 사용되는 많은 경우에서, 한 값은 ‘일반적인 케이스’이고 다른 값은 조건이 충족되지 않을 때만 사용되는 ‘예외적인 케이스’인 것처럼 보입니다. 이 조건문 문법은 이러한 패턴을 좀 더 명확하게 만듭니다:

contents = ((doc + '\n') if doc else '')

저는 위 문장을 “여기서 contents 는 보통 doc+'\n' 값을 할당받고; 가끔 doc 가 비어있을 때 예외적인 경우 빈 문자열이 반환됨”으로 해석했습니다. 명확한 일반적이고 비일반적인 경우가 없는 곳에서 조건식을 자주 사용할지는 의문입니다.

언어 수준의 문법에 주변 조건식 포함을 요구해야 하는지에 대한 논의가 있었습니다. 이 결정은 Python 언어의 문법에서는 괄호를 필수 로 하지 않기로 했지만, 스타일적인 문제로 저는 항상 괄호를 사용하는 것이 좋다고 생각합니다. 다음 두 문장을 고려해 보십시오:

# 첫 번째 버전 -- 괄호 없음
level = 1 if logging else 0

# 두 번째 버전 -- 괄호 있음
level = (1 if logging else 0)

첫 번째 버전에서는 독자가 해당 구문을 ‘level = 1’, ‘if logging’, ‘else 0’으로 그룹화하여, 조건문이 level 에 대한 할당을 결정하는지 생각할 수 있습니다. 제 의견으로는 두 번째 버전이 더 자연스러운데, 이 버전은 할당이 항상 이루어지며 선택되는 것이 두 가지 값 사이의 선택이라는 것을 명확하게 하기 때문입니다.

대괄호를 포함하는 또 다른 이유는 다음과 같습니다: 리스트 컴프리헨션과 람다 함수의 몇몇 특이한 조합이 잘못된 조건 표현식처럼 보일 수 있습니다. 일부 예시는 :pep:`308`을 참조하십시오. 조건 표현식 주위에 괄호를 사용하면 이 경우를 피할 수 있습니다.

더 보기

PEP 308: 조건 표현식

PEP는 Guido van Rossum과 Raymond D. Hettinger가 작성하고; Thomas Wouters가 구현했습니다.

PEP 309: 부분 함수 적용

functools 모듈은 함수형 스타일 프로그래밍 도구를 담을 목적으로 합니다.

이 모듈의 유용한 도구 중 하나는 partial() 함수입니다. 함수형 방식으로 작성된 프로그램의 경우, 일부 매개변수가 채워진 기존 함수의 변형을 구성하고 싶을 때가 있을 것입니다. 파이썬 함수 f(a, b, c) 를 가정해 보세요. f(1, b, c) 와 동등한 새로운 함수 g(b, c) 를 만들 수 있습니다. 이를 “부분 함수 적용”이라고 합니다.

partial()(function, arg1, arg2, ... kwarg1=value1, kwarg2=value2) 와 같은 인자를 받습니다. 결과 객체는 콜러블이므로, 채워진 인자로 function 을 호출하기 위해 결과 객체를 호출할 수 있습니다.

다음은 작지만 현실적인 예시입니다:

import functools

def log (message, subsystem):
    "Write the contents of 'message' to the specified subsystem."
    print '%s: %s' % (subsystem, message)
    ...

server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')

PyGTK를 사용하는 프로그램에서 가져온 또 다른 예시가 있습니다. 여기서는 컨텍스트에 민감한 팝업 메뉴가 동적으로 구성되고 있습니다. 메뉴 옵션에 제공된 콜백은 open_item() 메서드를 부분 적용하여 사용한 버전이며, 여기서 첫 번째 인자가 이미 제공되었습니다.

...
class Application:
    def open_item(self, path):
       ...
    def init (self):
        open_func = functools.partial(self.open_item, item_path)
        popup_menu.append( ("Open", open_func, 1) )

functools 모듈의 또 다른 함수는 잘 작동하는 데코레이터를 작성하는 데 도움이 되는 update_wrapper(wrapper, wrapped) 함수입니다. :func:`update_wrapper`는 래핑된 함수의 추적 백(traceback)을 더 쉽게 이해할 수 있도록 이름, 모듈, docstring 속성을 래퍼 함수로 복사합니다. 예를 들어, 다음과 같이 작성할 수 있습니다:

def my_decorator(f):
    def wrapper(*args, **kwds):
        print 'Calling decorated function'
        return f(*args, **kwds)
    functools.update_wrapper(wrapper, f)
    return wrapper

:func:`wraps`는 자체 데코레이터 내부에서 래핑된 함수의 정보를 복사하는 데 사용할 수 있는 데코레이터입니다. 이전 예시의 대안 버전은 다음과 같습니다:

def my_decorator(f):
    @functools.wraps(f)
    def wrapper(*args, **kwds):
        print 'Calling decorated function'
        return f(*args, **kwds)
    return wrapper

더 보기

PEP 309: 부분 함수 적용

PEP는 Peter Harris가 제안하고 작성했으며; Hye-Shik Chang과 Nick Coghlan이 구현했고, Raymond Hettinger가 적용했습니다.

PEP 314: Python 소프트웨어 패키지용 메타데이터 v1.1

간단한 의존성 지원이 Distutils에 추가되었습니다. setup() 함수는 이제 requires, provides, 및 obsoletes 키워드 매개변수를 가집니다. sdist 명령을 사용하여 소스 배포판을 빌드하면 의존성 정보가 PKG-INFO 파일에 기록됩니다.

또 다른 새로운 키워드 매개변수는 download_url 이며, 이 값은 패키지의 소스 코드로 향하는 URL로 설정되어야 합니다. 이는 이제 패키지 인덱스에서 항목을 검색하고, 패키지에 대한 의존성을 결정하며, 필요한 패키지를 다운로드할 수 있음을 의미합니다.

VERSION = '1.0'
setup(name='PyPackage',
      version=VERSION,
      requires=['numarray', 'zlib (>=1.1.4)'],
      obsoletes=['OldPackage']
      download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'
                    % VERSION),
     )

https://pypi.org의 Python 패키지 인덱스에 또 다른 개선점은 패키지의 소스 아카이브와 바이너리 아카이브를 저장하는 것입니다. 새로운 upload Distutils 명령어는 패키지를 리포지토리에 업로드합니다.

패키지를 업로드하려면 먼저 sdist Distutils 명령을 사용하여 배포판을 빌드할 수 있어야 합니다. 이것이 작동하면, 파키지를 PyPI 아카이브에 추가하기 위해 python setup.py upload 를 실행할 수 있습니다. 선택적으로, --sign--identity 옵션을 제공하여 패키지에 GPG 서명을 할 수 있습니다.

패키지 업로드는 Martin von Löwis와 Richard Jones가 구현했습니다.

더 보기

PEP 314: Python 소프트웨어 패키지용 메타데이터 v1.1

PEP는 A.M. Kuchling, Richard Jones, 그리고 Fred Drake가 제안하고 작성했으며; Richard Jones와 Fred Drake가 구현했습니다.

PEP 328: 절대 및 상대 임포트

PEP 328 의 더 간단한 부분은 Python 2.4에서 구현되었습니다: 따옴표를 사용하여 모듈에서 임포트하는 이름들을 from ... import ... ` 문으로 묶을 수 있게 되어, 여러 다른 이름을 가져오기가 쉬워졌습니다.

더 복잡한 부분은 Python 2.5에서 구현되었습니다: 이제 모듈 임포트를 절대 임포트 또는 패키지 상대 임포트로 지정할 수 있습니다. 추후 버전에서는 절대 임포트가 기본값이 되는 방향으로 나아갈 계획입니다.

다음과 같은 패키지 디렉토리를 가지고 있다고 가정해 봅시다:

pkg/
pkg/__init__.py
pkg/main.py
pkg/string.py

This defines a package named pkg containing the pkg.main and pkg.string submodules.

main.py 모듈의 코드를 고려해 보세요. 만약 import string` 문이 실행되면 어떻게 될까요? Python 2.4 이전 및 초기 버전에서는 상대 임포트를 수행하기 위해 먼저 패키지 디렉토리를 찾고, pkg/string.py`를 찾은 다음, 파일의 내용을 :mod:`pkg.string 모듈로 임포트하며, 이 모듈이 pkg.main 모듈 네임스페이스의 string 이름에 바인딩됩니다.

만약 원했던 것이 pkg.string 이었다면 괜찮습니다. 하지만 파이썬의 기본 string 모듈을 원한다면 어떨까요? pkg.string 무시하고 기본 모듈을 찾을 깨끗한 방법은 없습니다. 일반적으로 sys.modules 의 내용을 봐야 했으며, 이는 약간 지저분합니다. Holger Krekel의 py.std 패키지는 표준 라이브러리에서 임포트하는 더 깔끔한 방법을 제공하며, import py; py.std.string.join() 을 사용하지만, 이 패키지가 모든 파이썬 설치본에서 사용할 수 있는 것은 아닙니다.

상대 임포트에 의존하는 코드를 읽는 것도 덜 명확합니다. 독자가 어떤 모듈, 즉 :mod:`string`을 사용해야 하는지 아니면 :mod:`pkg.string`을 사용해야 하는지 혼란스러워할 수 있기 때문입니다. 파이썬 사용자들은 표준 라이브러리 모듈의 이름을 패키지의 하위 모듈 이름에 중복하지 않도록 빠르게 배웠지만, 미래 버전의 파이썬에서 추가된 새로운 모듈로 인해 서브모듈 이름이 사용되는 것을 막을 수는 없습니다.

Python 2.5에서는 from __future__ import absolute_import 지시문을 사용하여 import 의 동작을 절대 임포트로 전환할 수 있습니다. 이 절대 임포트 동작은 미래 버전(아마도 Python 2.7)에서 기본값이 될 것입니다. 절대 임포트가 기본값이 되면, import string 은 항상 표준 라이브러리 버전을 찾게 됩니다. 따라서 사용자들은 가능한 한 절대 임포트를 사용하기 시작하는 것이 좋으며, 코드에 from pkg import string 을 작성하는 것을 선호합니다.

from … import 형식을 사용할 때도 앞에 점(period)을 추가하여 상대 임포트가 여전히 가능합니다:

# pkg.string에서 이름 임포트
from .string import name1, name2
# pkg.string 임포트
from . import string

이것은 현재 패키지(relative to the current package)에 상대적인 string 모듈을 임포트하므로, pkg.main`에서는 이것이 :mod:`pkg.string`에서 *name1*과 *name2*를 임포트하게 됩니다. 추가되는 점들은 현재 패키지의 부모로부터 시작하는 상대 임포트를 수행합니다. 예를 들어, :mod:`A.B.C 모듈의 코드는 다음과 같이 할 수 있습니다:

from . import D                 # A.B.D 임포트
from .. import E                # A.E 임포트
from ..F import G               # A.F.G 임포트

앞에 붙는 점들은 import modname 형식의 임포트 문 위에서는 사용할 수 없으며, 오직 from ... import 형식에서만 사용 가능합니다.

더 보기

PEP 328 - 임포트: 복수 줄 및 절대/상대

Aahz가 작성하고 Thomas Wouters가 구현한 PEP입니다.

https://pylib.readthedocs.io/

Holger Krekel이 작성한 py 라이브러리로, py.std 패키지를 포함합니다.

PEP 338: 스크립트로 모듈 실행하기

Python 2.4에서 추가된 -m 스위치는 모듈을 스크립트로 실행하는 기능이 더 많은 기능을 갖게 되었습니다. 원래 파이썬 인터프리터 내부의 C 코드로 구현되었던 것과 달리, 이제 이 스위치는 새 모듈인 :mod:`runpy`에 있는 구현을 사용합니다.

runpy 모듈은 더 정교한 임포트 메커니즘을 구현하여 pychecker.checker 와 같은 패키지 내의 모듈을 실행하는 것이 가능해졌습니다. 이 모듈은 또한 zipimport 모듈과 같은 대체 임포트 메커니즘도 지원합니다. 이는 .zip 압축 파일의 경로를 sys.path 에 추가하고, -m 스위치를 사용하여 해당 아카이브의 코드를 실행할 수 있다는 의미입니다.

더 보기

PEP 338 - 모듈을 스크립트로 실행하기

Nick Coghlan이 작성하고 구현한 PEP입니다.

PEP 341: try/except/finally 통합

Python 2.5 이전까지, try 문은 두 가지 방식으로 사용되었습니다. 항상 코드가 실행되도록 보장하기 위해 finally 블록을 사용하거나, 특정 예외를 포착하기 위해 하나 이상의 except 블록을 사용할 수 있었습니다. 하지만 이 두 종류의 except 블록과 finally 블록을 결합할 수는 없었습니다. 그 이유는 결합된 버전에 대한 적절한 바이트코드를 생성하는 것이 복잡했고, 결합된 구문의 의미론이 무엇이어야 할지 명확하지 않았기 때문입니다.

Guido van Rossum은 Java를 사용하며, Java는 except 블록과 finally 블록을 결합하는 것의 등가 기능을 지원한다는 것을 어느 정도 연구했습니다. 그리고 이것이 해당 문법이 의미해야 하는 바를 명확하게 했습니다. Python 2.5부터는 이제 다음과 같이 작성할 수 있습니다:

try:
    block-1 ...
except Exception1:
    handler-1 ...
except Exception2:
    handler-2 ...
else:
    else-block
finally:
    final-block

block-1 에 있는 코드가 실행됩니다. 만약 코드에서 예외가 발생하면, 다양한 except 블록이 테스트됩니다: 예외가 Exception1 클래스인지 확인하고, 그러면 handler-1 이 실행됩니다; 그렇지 않으면 Exception2 인지 확인하여 handler-2 가 실행되고, 이런 식으로 계속됩니다. 예외가 발생하지 않으면, else-block 이 실행됩니다.

이전에 무슨 일이 있었든 관계없이, 코드 블록이 완료되고 모든 예외가 처리되면 final-block 은 한 번 실행됩니다. 예외 핸들러나 else-block 에 오류가 있어도 새로운 예외가 발생하면, final-block 의 코드는 여전히 실행됩니다.

더 보기

PEP 341 - try-except와 try-finally 통합

PEP를 Georg Brandl이 작성했으며, Thomas Lee가 구현했습니다.

PEP 342: 새로운 제너레이터 기능들

Python 2.5는 제너레이터에 값을 전달 하는 간단한 방법을 추가합니다. Python 2.3에서 소개된 것처럼, 제너레이터는 출력을 생성하기만 합니다. 즉, 제너레이터의 코드가 이터레이터를 만들기 위해 호출된 후에는 그 실행이 다시 시작될 때 함수에 새로운 정보를 전달할 방법이 없었습니다. 가끔 일부 정보를 전달하는 능력이 유용할 수 있습니다. 이에 대한 임시적인 해결책으로는 제너레이터 코드가 전역 변수를 참조하도록 만들거나, 호출자가 수정할 수 있는 변경 가능한 객체를 전달하는 것이 포함됩니다.

기본 제너레이터에 대한 기억을 상기하기 위해 간단한 예제를 소개합니다:

def counter (maximum):
    i = 0
    while i < maximum:
        yield i
        i += 1

counter(10) 를 호출하면, 0부터 9까지의 값을 반환하는 이테레이터가 반환됩니다. yield 문을 만나면, 이테레이터는 제공된 값을 반환하고 함수의 실행을 일시 중지하면서 지역 변수들을 보존합니다. 실행은 이테레이터의 다음 호출인 next() 메서드에서 재개되며, yield 문 이후부터 계속됩니다.

Python 2.3에서 yield`는 문장이었습니다. 값을 반환하지 않았습니다. 2.5부터는 :keyword:!yield`가 이제 표현식(expression)이 되었으며, 변수에 할당하거나 또는 달리 사용할 수 있는 값을 반환합니다:

val = (yield i)

위 예제에서처럼, 반환된 값으로 무언가를 할 때는 yield 표현식 주위에 항상 괄호를 넣는 것이 좋습니다. 괄호가 항상 필요한 것은 아니지만, 필요할 때를 기억하는 것보다 항상 추가하는 것이 더 쉽습니다.

PEP 342 는 정확한 규칙을 설명합니다. 이것은 yield-표현식이 대입의 오른쪽에 있는 최상위 표현식에 발생할 때를 제외하고는 항상 괄호로 묶여야 한다는 것입니다. 이는 val = yield i 로 쓸 수도 있지만, val = (yield i) + 12 처럼 연산이 있을 때는 괄호를 사용해야 함을 의미합니다.)

값은 이의 send(value) 메서드를 호출하여 제너레이터로 보내집니다. 그러면 제너레이터 코드가 재개되고, yield 표현식은 지정된 value 를 반환합니다. 만약 일반적인 next() 메서드가 호출되면, yieldNone 을 반환합니다.

이전 예시를 내부 카운터값을 변경할 수 있도록 수정했습니다.

def counter (maximum):
    i = 0
    while i < maximum:
        val = (yield i)
        # 값이 제공되면 카운터를 변경합니다
        if val is not None:
            i = val
        else:
            i += 1

카운터값을 변경하는 예시는 다음과 같습니다:

>>> it = counter(10)
>>> print it.next()
0
>>> print it.next()
1
>>> print it.send(8)
8
>>> print it.next()
9
>>> print it.next()
Traceback (most recent call last):
  File "t.py", line 15, in ?
    print it.next()
StopIteration

yield`는 일반적으로 :const:`None`을 반환하므로, 항상 경우를 확인해야 합니다. :meth:`send 메서드가 제너레이터 함수를 재개하는 데 사용되는 유일한 메서드임을 확신할 수 없다면, 표현식에서 그 값을 바로 사용하지 마세요.

send() 외에도, 제너레이터에는 다른 두 가지 새로운 메서드가 있습니다:

  • throw(type, value=None, traceback=None) 는 제너레이터 내에서 예외를 발생시키는 데 사용됩니다; 이 예외는 제너레이터의 실행이 일시 중지된 yield 표현식에 의해 발생합니다.

  • close`는 반복을 종료하기 위해 제너레이터 내부에 새로운 :exc:`GeneratorExit() 예외를 발생시킵니다. 이 예외를 받으면, 제너레이터의 코드는 GeneratorExit 또는 StopIteration 중 하나를 발생시켜야 합니다. GeneratorExit 예외를 잡고 값을 반환하는 것은 불법이며 :exc:`RuntimeError`를 유발합니다. 만약 함수가 다른 예외를 발생시킨다면, 그 예외는 호출자에게 전파됩니다. 또한 :meth:`close`는 제너레이터가 가비지 컬렉션되는 경우 Python의 가비지 컬렉터에 의해서도 호출됩니다.

    GeneratorExit`이 발생할 정리 코드를 실행해야 한다면, :exc:`GeneratorExit`를 잡는 것보다는 ``try: ... finally:` 구문을 사용하는 것이 좋습니다.

이러한 변경들의 누적된 효과는 제너레이터를 정보의 일방향 생성기에서 생산자 및 소비자 기능을 모두 가진 구조로 전환시킨 것입니다.

제너레이터는 또한 코루틴 이 되어 더 일반화된 형태의 서브루틴이 됩니다. 서브루틴은 한 지점에서 시작하여 다른 한 지점(함수의 맨 위와 return 문)에서 종료되지만, 코루틴은 여러 다른 지점에서 시작되고 종료되며 재개될 수 있습니다 ( yield 구문). 파이썬에서 코루틴을 효과적으로 사용하는 패턴을 찾아야 합니다.

The addition of the close() method has one side effect that isn’t obvious. close() is called when a generator is garbage-collected, so this means the generator’s code gets one last chance to run before the generator is destroyed. This last chance means that try...finally statements in generators can now be guaranteed to work; the finally clause will now always get a chance to run. The syntactic restriction that you couldn’t mix yield statements with a try...finally suite has therefore been removed. This seems like a minor bit of language trivia, but using generators and try...finally is actually necessary in order to implement the with statement described by PEP 343. I’ll look at this new statement in the following section.

이 변화의 또 다른 더 심오한 효과는 다음과 같습니다. 이전에는 제너레이터의 gi_frame 속성은 항상 프레임 객체였습니다. 이제는 제너레이터가 소진된 후 gi_frameNone 일 수 있게 되었습니다.

더 보기

PEP 342 - 향상된 제너레이터를 이용한 코루틴

PEP는 Guido van Rossum과 Phillip J. Eby가 작성하고 Phillip J. Eby가 구현했습니다. 이 문서는 코루틴으로서의 생성기를 좀 더 복잡하게 사용하는 몇 가지 예시를 포함합니다.

이러한 기능들의 이전 버전은 Raymond Hettinger가 :pep:`288`에서, 그리고 Samuele Pedroni가 :pep:`325`에서 제안되었습니다.

https://en.wikipedia.org/wiki/Coroutine

코루틴에 대한 위키피디아 항목입니다.

https://web.archive.org/web/20160321211320/http://www.sidhe.org/~dan/blog/archives/000178.html

Perl 관점에서 코루틴을 설명한 글이며, Dan Sugalski가 작성했습니다.

PEP 343: ‘with’ 문

with’ 문은 이전에 정리 코드를 실행하도록 try...finally 블록을 사용했던 코드를 명확히 합니다. 본 섹션에서는 해당 문이 일반적으로 사용될 방법을 논의할 것입니다. 다음 섹션에서는 구현 세부 사항을 살펴보고 이 문과 함께 사용할 객체를 작성하는 방법을 보여드리겠습니다.

with’ 문은 기본적인 구조는 다음과 같은 새로운 제어 흐름 구조입니다:

with expression [as variable]:
    with-block

표현식이 평가되고, 컨텍스트 관리 프로토콜을 지원하는 객체(즉, __enter__()__exit__() 메서드를 가진 객체)를 반환해야 합니다.

The object’s __enter__() is called before with-block is executed and therefore can run set-up code. It also may return a value that is bound to the name variable, if given. (Note carefully that variable is not assigned the result of expression.)

with-block 실행이 완료된 후, 블록에서 예외가 발생했더라도 객체의 __exit__() 메서드가 호출되므로 정리 코드를 실행할 수 있습니다.

Python 2.5에서 스탬트를 활성화하려면 모듈에 다음 지시문을 추가해야 합니다:

from __future__ import with_statement

해당 스탬트는 Python 2.6부터 항상 활성화됩니다.

일부 표준 Python 객체는 이제 컨텍스트 관리 프로토콜을 지원하며 ‘with’ 문에서 사용할 수 있습니다. 파일 객체가 그 예입니다:

with open('/etc/passwd', 'r') as f:
    for line in f:
        print line
        ... more processing code ...

이 구문이 실행된 후에는, for 루프가 블록 중간에 예외를 발생시키더라도 f 의 파일 객체는 자동으로 닫힙니다.

참고

이 경우, fopen() 에 의해 생성된 것과 동일한 객체입니다. 왜냐하면 __enter__()self 를 반환하기 때문입니다.

threading 모듈의 락(lock)과 조건 변수도 ‘with’ 문을 지원합니다:

lock = threading.Lock()
with lock:
    # 임계 코드 섹션입니다
    ...

이 블록이 실행되기 전에 락이 획득되고, 블록이 완료되면 항상 해제됩니다.

decimal 모듈의 새로운 localcontext() 함수는 현재의 십진수 컨텍스트를 저장하고 복원하기 쉽게 만듭니다. 이는 계산을 위해 원하는 정밀도 및 반올림 특성을 캡슐화합니다:

from decimal import Decimal, Context, localcontext

# 기본 정밀도인 28자리로 표시합니다.
v = Decimal('578')
print v.sqrt()

with localcontext(Context(prec=16)):
    # 이 블록의 모든 코드는 정밀도 16자리를 사용합니다.
    # 원래 컨텍스트는 블록을 벗어날 때 복원됩니다.
    print v.sqrt()

컨텍스트 관리자 작성하기

내부적으로 ‘with’ 문은 상당히 복잡합니다. 대부분의 사람들은 기존 객체와 함께 ‘with’만 사용하므로 이러한 세부 사항을 알 필요가 없습니다. 따라서 원하시면 이 섹션 나머지는 건너뛰셔도 됩니다. 새로운 객체의 작성자는 기본 구현의 세부 사항을 이해해야 하며 계속 읽는 것이 좋습니다.

컨텍스트 관리 프로토콜에 대한 높은 수준의 설명은 다음과 같습니다:

  • 표현식이 평가되어 “컨텍스트 관리자”라고 불리는 객체를 반환해야 합니다. 컨텍스트 관리자는 __enter__()__exit__() 메서드를 가지고 있어야 합니다.

  • 컨텍스트 관리자의 __enter__() 메서드가 호출됩니다. 반환된 값은 VAR 에 할당됩니다. 'as VAR' 절이 없으면, 그 값은 단순히 폐기됩니다.

  • BLOCK 의 코드가 실행됩니다.

  • BLOCK 에서 예외가 발생하면, 해당 예외 세부 정보와 sys.exc_info() 에 의해 반환되는 것과 동일한 값을 사용하여 __exit__(type, value, traceback) 이 호출됩니다. 메서드의 반환 값은 예외를 재발할지 여부를 제어합니다. 모든 거짓 값은 예외를 다시 발생시키며, True 는 이를 억제하는 결과를 초래합니다. 예외를 억제하고 싶을 때는 매우 드문 경우에만 그럴 것이기 때문입니다. 그렇지 않으면 코드 내에 ‘with ‘ 스탬트를 포함한 작성자는 아무 문제도 발생하지 않았다는 것을 결코 알지 못할 것입니다.

  • BLOCK 에서 예외가 발생하지 않으면, __exit__() 메서드는 여전히 호출되지만, type, value, traceback 은 모두 None 입니다.

예시를 들어 보겠습니다. 상세한 코드를 제시하지 않고, 트랜잭션을 지원하는 데이터베이스에 필요한 메서드들만 개략적으로 설명하겠습니다.

(데이터베이스 용어에 익숙하지 않은 분들을 위해: 데이터베이스의 일련의 변경 사항들은 트랜잭션으로 그룹화됩니다. 트랜잭션은 모두 데이터베이스에 기록되는 커밋되거나, 모든 변경 사항이 폐기되고 데이터베이스가 변경되지 않는 롤백될 수 있습니다. 더 많은 정보는 모든 데이터베이스 교과서를 참고하십시오.)

데이터베이스 연결을 나타내는 객체가 있다고 가정해 보겠습니다. 우리의 목표는 사용자가 다음과 같은 코드를 작성할 수 있도록 하는 것입니다:

db_connection = DatabaseConnection()
with db_connection as cursor:
    cursor.execute('insert into ...')
    cursor.execute('delete from ...')
    # ... 추가 작업 ...

블록 내부의 코드가 오류 없이 실행되면 트랜잭션은 커밋되어야 하고, 예외가 발생하면 롤백되어야 합니다. 제가 가정할 :class:`DatabaseConnection`에 대한 기본 인터페이스는 다음과 같습니다:

class DatabaseConnection:
    # 데이터베이스 인터페이스
    def cursor (self):
        "커서 객체를 반환하고 새 트랜잭션을 시작합니다."
    def commit (self):
        "현재 트랜잭션을 커밋합니다."
    def rollback (self):
        "현재 트랜잭션을 롤백합니다."

__enter__() 메서드는 새 트랜잭션을 시작하기만 하면 되므로 매우 간단합니다. 이 애플리케이션의 경우 결과 커서 객체가 유용한 결과가 될 것이므로, 이 메서드는 이를 반환합니다. 그러면 사용자는 ‘with ‘ 구문에 as cursor 를 추가하여 커서를 변수 이름에 바인딩할 수 있습니다.

class DatabaseConnection:
    ...
    def __enter__ (self):
        # 새 트랜잭션을 시작하는 코드
        cursor = self.cursor()
        return cursor

__exit__() 메서드가 가장 복잡한데, 왜냐하면 대부분의 작업이 이 메서드에서 처리되어야 하기 때문입니다. 이 메서드는 예외가 발생했는지 확인해야 합니다. 예외가 없으면 트랜잭션은 커밋됩니다. 예외가 있으면 트랜잭션은 롤백됩니다.

아래 코드에서는 실행이 함수 끝까지 진행되어 기본값인 None 을 반환할 것입니다. None 은 false 값이므로 예외가 자동으로 다시 발생합니다. 원한다면, 표시된 위치에 return 문을 추가하여 더 명시적으로 만들 수 있습니다.

class DatabaseConnection:
    ...
    def __exit__ (self, type, value, tb):
        if tb is None:
            # 예외가 없으므로 커밋
            self.commit()
        else:
            # 예외가 발생했으므로 롤백합니다.
            self.rollback()
            # return False

contextlib 모듈

새로운 contextlib 모듈은 ‘with’ 문과 함께 사용하기 위해 유용한 일부 함수와 데코레이터를 제공합니다.

데코레이터는 @~contextlib.contextmanager`라고 불리며, 새로운 클래스를 정의하는 대신 단일 제너레이터 함수를 작성할 있게 해줍니다. 제너레이터는 정확히 하나의 값을 `yield`해야 합니다. :keyword:`yield`까지의 코드는 :meth:`~object.__enter__ 메서드로 실행되며, yield`된 값은 ‘:keyword:`with’ 문의 ‘as’ 절에 있는 변수에 바인딩될 메서드의 반환 값이 됩니다. yield 이후의 코드는 __exit__() 메서드에서 실행됩니다. 블록 내에서 발생하는 모든 예외는 yield 문에 의해 발생됩니다.

이전 섹션의 데이터베이스 예제는 이 데코레이터를 사용해서 다음과 같이 작성할 수 있습니다:

from contextlib import contextmanager

@contextmanager
def db_transaction (connection):
    cursor = connection.cursor()
    try:
        yield cursor
    except:
        connection.rollback()
        raise
    else:
        connection.commit()

db = DatabaseConnection()
with db_transaction(db) as cursor:
    ...

contextlib 모듈에는 또한 여러 컨텍스트 관리자를 결합하는 nested(mgr1, mgr2, ...) 함수가 있어 중첩된 :keyword: with`’ 문을 작성할 필요가 없습니다. 이 예제에서는 단일 with ‘ 문이 데이터베이스 트랜잭션을 시작하고 스레드 잠금을 획득합니다:

lock = threading.Lock()
with nested (db_transaction(db), lock) as (cursor, locked):
    ...

마지막으로, closing(object) 함수는 object 를 반환하여 변수에 바인딩할 수 있게 하고, 블록 끝에서 object.close 를 호출합니다:

import urllib, sys
from contextlib import closing

with closing(urllib.urlopen('http://www.yahoo.com')) as f:
    for line in f:
        sys.stdout.write(line)

더 보기

PEP 343 - “with” 문

Guido van Rossum과 Nick Coghlan이 작성하고 Mike Bland, Guido van Rossum, Neal Norwitz가 구현한 PEP입니다. 이 PEP는 :keyword: with`’ 문에 대해 생성된 코드를 보여주며, 해당 문이 어떻게 작동하는지 학습하는 데 도움이 될 수 있습니다.

contextlib 모듈의 설명서입니다.

PEP 352: 예외를 새 스타일 클래스로 사용하기

예외 클래스는 이제 기본 클래스뿐 아니라 새로운 스타일의 클래스로도 작성할 수 있게 되었으며, 내장 Exception 클래스와 모든 표준 내장 예외(NameError, ValueError 등)가 모두 새 스타일 클래스입니다.

예외의 상속 계층 구조가 약간 재배치되었습니다. 2.5 버전에서는 다음과 같은 상속 관계를 가집니다:

BaseException       # Python 2.5에서 새로 추가됨
|- KeyboardInterrupt
|- SystemExit
|- Exception
   |- (현재 모든 내장 예외)

이 재배치는 사람들이 프로그램 오류를 나타내는 모든 예외를 잡고 싶어 하는 경우가 많았기 때문에 이루어졌습니다. 하지만 KeyboardInterrupt`와 :exc:`SystemExit`는 오류가 아니며, 보통 사용자가 :kbd:`Control-C`를 누르거나 코드가 :func:`sys.exit`을 호출하는 명시적인 동작을 나타냅니다. ``except:` 구문은 모든 예외를 잡기 때문에, 일반적으로 이들을 다시 발생시키려면 :exc:`KeyboardInterrupt`와 :exc:`SystemExit`를 목록으로 지정해야 합니다. 일반적인 패턴은 다음과 같습니다:

try:
    ...
except (KeyboardInterrupt, SystemExit):
    raise
except:
    # 오류 기록...
    # 프로그램 실행 계속...

Python 2.5에서는 이제 except Exception``을 작성하여 동일한 결과를 얻을 있으며, 일반적으로 오류를 나타내는 모든 예외를 잡지만 :exc:`KeyboardInterrupt`와 :exc:`SystemExit`는 제외합니다. 이전 버전과 마찬가지로 ``except: 구문은 여전히 모든 예외를 잡습니다.

The goal for Python 3.0 is to require any class raised as an exception to derive from BaseException or some descendant of BaseException, and future releases in the Python 2.x series may begin to enforce this constraint. Therefore, I suggest you begin making all your exception classes derive from Exception now. It’s been suggested that the bare except: form should be removed in Python 3.0, but Guido van Rossum hasn’t decided whether to do this or not.

문자열을 예외로 발생시키는 것, 즉 raise "Error occurred" 구문의 경우 Python 2.5에서는 사용이 중단 예정이며 경고를 발생시킬 것입니다. 목표는 몇몇 릴리스에서 문자열 예외 기능을 제거하는 것입니다.

더 보기

PEP 352 - 예외의 필수 슈퍼클래스

Brett Cannon이 작성하고 Guido van Rossum이 기여했으며, Brett Cannon이 구현한 PEP입니다.

PEP 353: 인덱스 유형으로 ssize_t 사용하기

Python의 C API에 걸쳐 광범위하게 변경된 내용으로, int 대신 새로운 Py_ssize_t 타입 정의를 사용하여, 인터프리터가 64비트 플랫폼에서 더 많은 데이터를 처리할 수 있게 합니다. 이 변경은 32비트 플랫폼에서의 파이썬 용량에는 영향을 주지 않습니다.

파이썬 인터프리터의 다양한 부분은 크기나 카운트를 저장하기 위해 C의 int 타입을 사용했습니다. 예를 들어, 리스트나 튜플의 항목 수는 int 에 저장되었습니다. 대부분의 64비트 플랫폼용 C 컴파일러는 여전히 int 를 32비트 타입으로 정의하므로, 이는 리스트가 최대 2**31 - 1 = 2147483647개의 항목만 가질 수 있음을 의미했습니다. (실제로는 64비트 C 컴파일러가 사용할 수 있는 몇 가지 다른 프로그래밍 모델들이 있습니다– 토론을 보려면 https://unix.org/version2/whatsnew/lp64_wp.html을 참조하십시오 – 하지만 가장 일반적으로 사용 가능한 모델은 int 를 여전히 32비트로 유지합니다.)

2147483647개 항목이라는 제한은 32비트 플랫폼에서는 실제로 중요하지 않습니다. 왜냐하면 길이 제한에 도달하기 전에 메모리가 부족해지기 때문입니다. 리스트의 각 항목은 포인터 공간(4바이트)과 해당 항목을 나타내는 :c:type:`PyObject`에 필요한 공간이 필요합니다. 2147483647*4는 이미 32비트 주소 공간이 포함할 수 있는 바이트보다 많습니다.

하지만, 64비트 플랫폼에서는 해당 양의 메모리를 다룰 수 있습니다. 그런 크기의 리스트에 대한 포인터는 단지 16 GiB의 공간만 필요하므로, 파이썬 프로그래머가 그렇게 큰 리스트를 구성하는 것이 비합리적이지 않습니다. 따라서 파이썬 인터프리터를 :c:expr:`int`가 아닌 다른 타입을 사용하도록 변경해야 했으며, 이는 64비트 플랫폼에서 64비트 타입이 될 것입니다. 이 변경은 64비트 머신에서 비호환성을 야기할 것이므로, 64비트 사용자 수가 아직 비교적 적을 때 이번에 전환하는 것이 가치가 있다고 판단되었습니다. (5년 또는 10년 후에는 우리가 모두 64비트 머신을 사용할 수 있으며, 그때는 전환이 더 고통스러울 것입니다.)

이 변경은 C 확장 모듈의 저자들에게 가장 크게 영향을 미칩니다. Python 문자열과 리스트, 튜플 같은 컨테이너 유형은 이제 크기를 저장하기 위해 :c:type:`Py_ssize_t`을 사용합니다. :c:func:`PyList_Size`와 같은 함수는 이제 :c:type:`Py_ssize_t`을 반환하는 것이 일반적입니다. 따라서 확장 모듈의 코드는 변수 일부를 :c:type:`Py_ssize_t`으로 변경해야 할 수 있습니다.

PyArg_ParseTuple()Py_BuildValue() 함수에는 Py_ssize_t 에 대한 새로운 변환 코드인 n 이 추가되었습니다. PyArg_ParseTuple()s#t# 는 여전히 기본적으로 int 를 출력하지만, Python.h 을 포함하기 전에 매크로 PY_SSIZE_T_CLEAN 를 정의하여 이들을 Py_ssize_t 을 반환하도록 할 수 있습니다.

:pep:`353`에는 확장 저자들이 64비트 플랫폼 지원에 대해 학습해야 할 변환 지침 섹션이 있습니다.

더 보기

PEP 353 - 인덱스 유형으로 ssize_t 사용하기

PEP는 Martin von Löwis가 작성하고 구현했습니다.

PEP 357: ‘__index__’ 메서드

NumPy 개발팀은 새로운 특수 메서드, __index__() 를 추가하는 것 외에는 해결할 수 없는 문제가 있었습니다. [start:stop:step] 와 같은 슬라이스 표기법을 사용할 때 start, stop, 및 step 인덱스의 값 모두 정수 또는 긴 정수여야만 합니다. NumPy는 8비트, 16비트, 32비트 및 64비트의 부호 없는 및 부호 있는 정수에 해당하는 다양한 특수 정수 타입을 정의했지만, 이 타입들이 슬라이스 인덱스로 사용될 수 있음을 알릴 방법이 없었습니다.

슬라이싱은 기존의 __int__() 메서드를 사용할 수 없습니다. 해당 메서드는 정수로 강제 변환하는 데에도 사용되기 때문입니다. 슬라이싱이 :meth:`__int__`를 사용한다면, 부동 소수점 숫자도 합법적인 슬라이스 인덱스가 될 것이며 이는 명백히 바람직하지 않은 동작입니다.

대신 :meth:`__index__`라는 새로운 특수 메서드가 추가되었습니다. 이 메서드는 인수를 받지 않으며 사용할 슬라이스 인덱스를 반환하는 정수를 반환합니다. 예시:

class C:
    def __index__ (self):
        return self.value

반환 값은 파이썬 정수 또는 긴 정수 중 하나여야 합니다. 인터프리터는 반환된 타입이 올바른지 확인할 것이며, 이 요구 사항을 충족하지 못하면 :exc:`TypeError`를 발생시킵니다.

C 확장 모듈이 이 프로토콜을 구현할 수 있도록 C 레벨의 PyNumberMethods 구조체에 해당 멤버인 nb_index 슬롯이 추가되었습니다. PyNumber_Index(obj) 은 확장 코드에서 사용되어 __index__() 함수를 호출하고 그 결과를 검색하는 데 사용할 수 있습니다.

더 보기

PEP 357 - 모든 객체를 슬라이싱에 사용할 수 있도록 허용하기

PEP는 Travis Oliphant가 작성하고 구현했습니다.

이외의 언어 변경 사항

이곳에 Python 2.5 업데이트로 핵심 Python 언어에 적용된 모든 변경 사항을 설명합니다.

  • The dict type has a new hook for letting subclasses provide a default value when a key isn’t contained in the dictionary. When a key isn’t found, the dictionary’s __missing__(key) method will be called. This hook is used to implement the new defaultdict class in the collections module. The following example defines a dictionary that returns zero for any missing key:

    class zerodict (dict):
        def __missing__ (self, key):
            return 0
    
    d = zerodict({1:1, 2:2})
    print d[1], d[2]   # 1, 2 출력
    print d[3], d[4]   # 0, 0 출력
    
  • 8비트 및 유니코드 문자열 모두 공통 사용 사례를 단순화하는 새로운 partition(sep)rpartition(sep) 메서드를 가집니다.

    find(S) 메서드는 종종 인덱스를 가져오는 데 사용되며, 이 인덱스는 문자열을 슬라이스하여 구분자 앞뒤의 조각들을 얻는 데 사용됩니다. partition(sep) 은 이러한 패턴을 단일 메서드 호출로 간소화하며, 이는 구분자 이전의 부분 문자열, 구분자 자체 및 구분자 이후의 부분 문자열을 포함하는 3-튜플을 반환합니다. 구분자가 없으면, 튜플의 첫 번째 요소가 전체 문자열이고 나머지 두 요소는 비어 있습니다. rpartition(sep) 도 3-튜플을 반환하지만 문자열 끝부터 검색을 시작합니다. 여기서 ‘r’은 ‘반전(reverse)’을 의미합니다.

    일부 예시:

    >>> ('http://www.python.org').partition('://')
    ('http', '://', 'www.python.org')
    >>> ('file:/usr/share/doc/index.html').partition('://')
    ('file:/usr/share/doc/index.html', '', '')
    >>> (u'Subject: a quick question').partition(':')
    (u'Subject', u':', u' a quick question')
    >>> 'www.python.org'.rpartition('.')
    ('www.python', '.', 'org')
    >>> 'www.python.org'.rpartition(':')
    ('', '', 'www.python.org')
    

    (Raymond Hettinger의 제안에 따라 Fredrik Lundh가 구현했습니다.)

  • 문자열 타입의 startswith()endswith() 메서드는 이제 확인할 문자열 튜플을 허용합니다.

    def is_image_file (filename):
        return filename.endswith(('.gif', '.jpg', '.tiff'))
    

    (Tom Lynn의 제안에 따라 Georg Brandl이 구현했습니다.)

  • min()max() 내장 함수에는 이제 sort`의 ``key`() 인자와 유사한 key 키워드 매개변수가 추가되었습니다. 이 매개변수는 단일 인자를 받는 함수를 제공하며 리스트의 모든 값에 대해 호출됩니다. min()/:func:`max`는 이 함수로부터 가장 작거나 가장 큰 반환 값을 가진 요소를 반환합니다. 예를 들어, 리스트에서 가장 긴 문자열을 찾으려면 다음과 같이 할 수 있습니다:

    L = ['medium', 'longest', 'short']
    # 'longest'를 출력합니다.
    print max(L, key=len)
    # 사전순으로 'short'가 가장 큰 값을 가지므로 'short'를 출력합니다.
    print max(L)
    

    (Steven Bethard와 Raymond Hettinger가 기여함.)

  • 두 개의 새로운 내장 함수 `:func:`any`와 `:func:`all`은 이터레이터가 참 또는 거짓 값을 포함하는지 여부를 평가합니다. :func:`any`는 이터레이터에서 반환된 값이 하나라도 참이면 :const:`True`를 반환하며, 그렇지 않으면 :const:`False`를 반환합니다. :func:`all`은 이터레이터에서 반환된 모든 값이 참으로 평가될 때만 :const:`True`를 반환합니다. (Guido van Rossum이 제안했으며, Raymond Hettinger가 구현했습니다.)

  • 클래스의 __hash__() 메서드 결과는 이제 롱(long) 정수 또는 일반 정수일 수 있습니다. 롱 정수가 반환되면, 해당 값의 해시값이 사용됩니다. 이전 버전에서는 해시값이 반드시 일반 정수여야 했지만, 2.5 버전에서 id() 내장 함수가 항상 음수가 아닌 숫자를 반환하도록 변경되었고, 사용자들은 종종 __hash__() 메서드에서 id(self) 를 사용합니다 (비권장).

  • ASCII는 이제 모듈의 기본 인코딩입니다. 더 이상 모듈이 8비트 문자를 가진 문자열 리터럴을 포함하지만 인코딩 선언문이 없는 경우 구문 오류가 발생합니다. Python 2.4에서는 이것이 경고를 유발했을 뿐, 구문 오류는 아니었습니다. :pep:`263`에서 모듈의 인코딩을 선언하는 방법을 참조하십시오. 예를 들어, 소스 파일 상단 근처에 다음과 같은 줄을 추가할 수 있습니다:

    # -*- coding: latin1 -*-
    
  • 새 경고, `:class:`UnicodeWarning``이 기본 ASCII 인코딩을 사용하여 유니코드 문자열과 8비트 문자열을 비교하려고 시도할 때 발생합니다. 비교 결과는 거짓입니다:

    >>> chr(128) == unichr(128)   # chr(128)를 유니코드로 변환할 수 없습니다.
    __main__:1: UnicodeWarning: Unicode equal comparison failed
      to convert both arguments to Unicode - interpreting them
      as being unequal
    False
    >>> chr(127) == unichr(127)   # chr(127)는 변환할 수 있습니다.
    True
    

    이전에는 UnicodeDecodeError 예외가 발생했지만, 2.5 버전에서는 사전을 접근할 때 당황스러운 문제가 발생할 수 있었습니다. unichr(128) 를 조회했는데 키로 chr(128) 가 사용되었다면, UnicodeDecodeError 예외가 발생했을 것입니다. 2.5의 다른 변경 사항들로 인해 이 예외는 사전을 구현하는 dictobject.c 의 코드에 의해 억제되는 대신 발생하게 되었습니다.

    그러한 비교에 대해 예외를 발생하는 것은 엄격하게 올바르지만, 변경 사항이 코드를 손상시켰을 수 있어 대신 `:class:`UnicodeWarning``이 도입되었습니다.

    (Marc-André Lemburg가 구현함.)

  • 파이썬 프로그래머들이 간혹 범하는 실수는 패키지 디렉토리에 __init__.py 모듈을 포함하는 것을 잊는 것입니다. 이 실수를 디버깅하는 것은 혼란스러울 수 있으며, 일반적으로 검색되는 모든 경로를 기록하려면 Python에 :option:-v`` 스위치를 사용하여 실행해야 합니다. Python 2.5에서는 가져오기가 패키지로 디렉토리를 인식할 수 있었지만 __init__.py`가 발견되지 않은 경우 새로운 :exc:`ImportWarning` 경고가 발생합니다. 이 경고는 기본적으로 조용히 무시됩니다. 경고 메시지를 표시하려면 Python 실행 시 :option:-Wd <-W>` 옵션을 제공하십시오. (Thomas Wouters가 구현했습니다.)

  • 클래스 정의의 기반 클래스 목록은 이제 비어 있을 수 있습니다. 예를 들어, 다음은 이제 허용됩니다:

    class C():
        pass
    

    (Brett Cannon이 구현함.)

대화형 인터프리터 변경 사항

대화형 인터프리터에서 quitexit 는 새로운 사용자가 종료를 시도할 때 다소 유용한 메시지를 받도록 오랫동안 문자열이었습니다:

>>> quit
'Use Ctrl-D (i.e. EOF) to exit.'

Python 2.5에서는 quitexit 이 여전히 문자열 표현을 생성하는 객체이지만, 호출 가능한 객체가 되었습니다. 이전에 quit() 또는 exit() 를 사용했던 초보자들은 이제 예상대로 인터프리터를 종료합니다. (Georg Brandl 구현.)

Python 실행 파일은 이제 표준 긴 옵션인 --help--version`을 허용하며, Windows에서는 도움말 메시지를 표시하기 위한 :option:/? <-?>` 옵션을 추가로 허용합니다. (Georg Brandl 구현.)

최적화들`

여러 최적화 중 일부는 2006년 5월 21일에서 28일까지 아이슬란드의 레이캬비크에서 열린 NeedForSpeed 스프린트에서 개발되었습니다. 이 스프린트는 CPython 구현의 속도 향상에 초점을 맞추었으며, EWT LLC가 자금을 지원하고 CCP Games로부터 현지 지원을 받았습니다. 이 스프린트에서 추가된 최적화 사항은 다음 목록에서 특별히 표시됩니다.

  • Python 2.4에 도입되었을 때, 내장된 setfrozenset 타입은 Python의 딕셔너리 타입을 기반으로 구축되었습니다. 2.5에서는 내부 데이터 구조가 세트를 구현하도록 사용자화되어, 그 결과 set은 메모리를 3분의 1 사용하며 어느 정도 더 빠릅니다. (Raymond Hettinger 구현.)

  • 하위 문자열 검색, 문자열 분할 및 문자 맵 인코딩 및 디코딩과 같은 일부 유니코드 작업의 속도가 향상되었습니다. (하위 문자열 검색 및 분할 개선은 Fredrik Lundh와 Andrew Dalke가 NeedForSpeed 스프린트에서 추가했습니다. 문자 맵 개선은 Walter Dörwald와 Martin von Löwis에 의해 이루어졌습니다.)

  • long(str, base) 함수는 중간 결과를 적게 계산하기 때문에 긴 자릿수 문자열에서 더 빨라졌습니다. 성능의 정점은 약 800~1000자리의 문자열이며, 이 경우 기능이 6배 빠릅니다. (Alan McIntyre가 기여하고 NeedForSpeed 스프린트에서 커밋되었습니다.)

  • 파일을 for line in file 로 반복하면서 파일 객체의 read()/readline()/readlines() 메서드를 호출하는 것은 이제 허용되지 않습니다. 반복은 내부 버퍼를 사용하며, read*() 메서드는 해당 버퍼를 사용하지 않습니다. 대신 다음 데이터를 반환하여 데이터가 순서에 맞지 않게 나타나게 합니다. 따라서 반복과 이러한 방법을 혼합하면 이제 ValueErrorread*() 메서드에서 발생합니다. (Thomas Wouters 구현.)

  • struct 모듈은 이제 구조 형식 문자열을 내부 표현으로 컴파일하고 이 표현을 캐싱하여 20%의 속도 향상을 가져왔습니다. (Bob Ippolito가 NeedForSpeed 스프린트에서 기여했습니다.)

  • re 모듈은 시스템의 malloc()free() 대신 Python의 할당자 함수로 전환하여 1~2%의 속도 향상을 얻었습니다. (Jack Diederich가 NeedForSpeed 스프린트에서 기여했습니다.)

  • 코드 생성기의 피프로 옵티마이저는 이제 표현식 내에서 간단한 상수 폴딩을 수행합니다. a = 2+3 와 같이 작성하면, 코드 생성기는 산술 연산을 수행하여 a = 5 에 해당하는 코드를 생성합니다. (Raymond Hettinger가 제안하고 구현했습니다.)

  • 함수 호출이 더 빨라졌는데, 이는 코드 객체가 가장 최근에 종료된 프레임(“좀비 프레임”)을 코드 객체의 내부 필드에 유지하여 다음번 코드 객체 인스턴스화 시 재사용하기 때문입니다. (초기 패치: Michael Hudson, 수정: Armin Rigo 및 Richard Jones; NeedForSpeed 스프린트에서 커밋됨.) 또한 프레임 객체가 약간 작아져 캐시 국지성(cache locality)을 개선하고 메모리 사용량을 줄일 수 있습니다. (Neal Norwitz 기여.)

  • Python의 내장 예외는 이제 New-style 클래스가 되었으며, 이는 인스턴스화 속도를 상당히 높였습니다. 따라서 Python 2.5에서의 예외 처리는 2.4보다 약 30% 빠릅니다. (NeedForSpeed 스프린트에서 Richard Jones, Georg Brandl 및 Sean Reifschneider가 기여했습니다.)

  • 임포트는 이제 시도한 경로를 캐시하여, 해당 경로의 존재 유무를 기록함으로써 인터프리터가 시작 시 open()stat() 호출을 더 적게 하도록 합니다. (Martin von Löwis와 Georg Brandl 기여.)

새로운, 개선된 그리고 제거된 모듈

표준 라이브러리는 Python 2.5에서 많은 개선과 버그 수정이 있었습니다. 가장 주목할 만한 변경 사항의 부분 목록을 모듈 이름별로 알파벳순으로 정리했습니다. 전체 변경 목록은 소스 트리 내의 Misc/NEWS 파일을 참조하거나 SVN 로그를 살펴보세요.

  • audioop 모듈이 이제 a-LAW 인코딩을 지원하며, u-LAW 인코딩 코드가 개선되었습니다. (Lars Immisch 기여.)

  • codecs 모듈은 증분형 코덱 지원을 추가했습니다. codec.lookup() 함수는 이제 튜플 대신 CodecInfo 인스턴스를 반환합니다. CodecInfo 인스턴스는 하위 호환성을 유지하기 위해 4개 튜플처럼 동작하며, 또한 encode, decode, incrementalencoder, incrementaldecoder, streamwriter, 그리고 streamreader 속성을 가집니다. 증분형 코덱은 여러 청크로 입력을 받아 처리하고 출력을 생성할 수 있으며, 이 출력은 전체 입력이 비증분형 코덱에 공급된 경우와 동일합니다. 자세한 내용은 codecs 모듈 문서를 참조하세요. (Walter Dörwald 설계 및 구현.)

  • collections 모듈은 표준 dict 타입을 상속하는 새로운 타입인 :class:`defaultdict`를 추가했습니다. 이 새 타입은 주로 딕셔너리처럼 동작하지만, 키가 존재하지 않을 때 기본값을 생성하여 요청된 키 값에 자동으로 딕셔너리에 추가합니다.

    defaultdict`의 생성자에 전달되는 번째 인수는 키가 요청되었지만 발견되지 않았을 때마다 호출되는 팩토리 함수입니다. 팩토리 함수는 인수를 받지 않으므로 :func:`list 또는 :func:`int`와 같은 내장 타입 생성기를 사용할 수 있습니다. 예를 들어, 다음과 같이 초기 문자를 기준으로 단어의 인덱스를 만들 수 있습니다:

    words = """Nel mezzo del cammin di nostra vita
    mi ritrovai per una selva oscura
    che la diritta via era smarrita""".lower().split()
    
    index = defaultdict(list)
    
    for w in words:
        init_letter = w[0]
        index[init_letter].append(w)
    

    index 를 출력하면 다음 출력이 나타납니다:

    defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'],
            'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'],
            'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'],
            'p': ['per'], 's': ['selva', 'smarrita'],
            'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}
    

    (Guido van Rossum 기여.)

  • collections 모듈에서 제공하는 deque 양방향 큐 타입에 이제 remove(value) 메서드가 추가되어, 큐에서 value 의 첫 번째 발생을 제거합니다. 만약 해당 값이 발견되지 않으면 ValueError 를 발생시킵니다. (Raymond Hettinger 기여.)

  • 새 모듈: contextlib 모듈에는 새로운 ‘with’ 문과 함께 사용할 헬퍼 함수들이 포함되어 있습니다. 이 모듈에 대한 자세한 내용은 contextlib 모듈 섹션을 참조하세요.

  • 새 모듈: cProfile 모듈은 기존의 profile 모듈을 C로 구현한 것으로, 훨씬 낮은 오버헤드를 가집니다. 이 모듈의 인터페이스는 profile`과 동일합니다: 함수를 프로파일링하려면 ``cProfile.run('main()')``를 실행하고, 프로파일 데이터를 파일에 저장할 있습니다. Hotshot 프로파일러가 C로 작성되었지만 :mod:!profile` 모듈의 인터페이스와 일치하지 않아 미래 버전의 Python에서 계속 유지될지는 알려지지 않았습니다. (Armin Rigo 기여.)

    또한, 프로파일러가 측정한 데이터를 분석하는 pstats 모듈은 Stats 생성자에 stream 인수를 제공하여 출력을 모든 파일 객체로 직접 지정하는 기능을 지원합니다. (Skip Montanaro 기여.)

  • 쉼표로 구분된 값 형식의 파일을 구문 분석하는 csv 모듈은 여러 개선 사항과 다수의 버그 수정을 받았습니다. 이제 csv.field_size_limit(new_limit) 함수를 호출하여 필드의 최대 크기를 바이트 단위로 설정할 수 있습니다. new_limit 인수를 생략하면 현재 설정된 제한이 반환됩니다. reader 클래스는 이제 소스에서 읽은 물리적 줄 수를 계산하는 line_num 속성을 가집니다. 레코드가 여러 물리적 줄에 걸쳐 있을 수 있으므로, :attr:`line_num`은 읽은 레코드의 수와 같지 않습니다.

    CSV 파서는 현재 여러 줄에 걸친 따옴표로 묶인 필드에 대해 더 엄격하게 처리합니다. 이전에는 줄이 끝날 때 종료되는 개행 문자 없이 따옴표로 묶인 필드 내에서 라인이 끝나면, 개행 문자가 반환된 필드에 삽입되었습니다. 이 동작은 필드 내에 캐리지 리턴 문자를 포함하는 파일을 읽을 때 문제를 일으켜, 코드가 새로운 줄을 삽입하지 않고 필드를 반환하도록 변경되었습니다. 따라서 필드 내의 개행 문자 내용이 중요하다면, 입력은 개행 문자를 보존하는 방식으로 라인으로 분할되어야 합니다.

    (Skip Montanaro 및 Andrew McNamara에 의해 기여됨.)

  • datetime 모듈의 datetime 클래스에는 이제 Josh Spoerri가 기여한 날짜 문자열을 파싱하기 위한 strptime(string, format) 메서드가 추가되었습니다. 이 메서드는 time.strptime() 및 :func:`time.strftime`와 동일한 형식 문자를 사용합니다:

    import datetime as dt
    
    ts = dt.datetime.strptime('10:13:15 2006-03-07',
                              '%H:%M:%S %Y-%m-%d')
    
  • difflib 모듈의 SequenceMatcher.get_matching_blocks() 메서드는 이제 일치하는 부분 시퀀스를 설명하는 최소한의 블록 목록을 반환함을 보장합니다. 이전에는 알고리즘이 때때로 일치하는 요소의 블록을 두 개의 리스트 항목으로 분할했습니다. (Tim Peters 작성.)

  • doctest 모듈에 모든 예제를 실행하지 않도록 유지하는 SKIP 옵션이 추가되었습니다. 이는 독자를 대상으로 하는 사용례 예제이며 실제 테스트 케이스는 아닌 코드 조각을 위한 것입니다.

    파일의 인코딩을 지정하기 위해 testfile() 함수와 DocFileSuite 클래스에 encoding 매개변수가 추가되었습니다. 이는 docstring 내에 포함된 테스트에서 비-ASCII 문자를 더 쉽게 사용할 수 있게 합니다. (Bjorn Tillenius 작성.)

  • email 패키지가 버전 4.0으로 업데이트되었습니다. (Barry Warsaw 작성.)

  • The fileinput module was made more flexible. Unicode filenames are now supported, and a mode parameter that defaults to "r" was added to the input() function to allow opening files in binary or universal newlines mode. Another new parameter, openhook, lets you use a function other than open() to open the input files. Once you’re iterating over the set of files, the FileInput object’s new fileno() returns the file descriptor for the currently opened file. (Contributed by Georg Brandl.)

  • gc 모듈에서 새로운 get_count() 함수는 세 GC 세대에 대한 현재 수거 횟수를 포함하는 3-튜플을 반환합니다. 이것은 가비지 컬렉터의 회계 정보이며, 이 카운트가 지정된 임계값에 도달하면 가비지 컬렉션 스윕이 수행됩니다. 기존 gc.collect() 함수는 이제 어떤 세대를 수거할지 지정하기 위해 0, 1 또는 2의 선택적 generation 인수를 받습니다. (Barry Warsaw 작성.)

  • heapq 모듈의 nsmallest()nlargest() 함수는 이제 min()/max() 함수와 sort() 메서드가 제공하는 것과 유사한 key 키워드 매개변수를 지원합니다. 예를 들어:

    >>> import heapq
    >>> L = ["short", 'medium', 'longest', 'longer still']
    >>> heapq.nsmallest(2, L)  # 사전 순으로 두 개의 낮은 요소를 반환합니다.
    ['longer still', 'longest']
    >>> heapq.nsmallest(2, L, key=len)   # 두 개의 짧은 요소를 반환합니다.
    ['short', 'medium']
    

    (Raymond Hettinger 작성.)

  • itertools.islice() 함수는 이제 start 및 step 인수에 대해 None 을 받습니다. 이는 슬라이스 객체의 속성과 더 호환되게 만들어, 다음과 같이 작성할 수 있게 합니다:

    s = slice(5)     # 슬라이스 객체를 만듭니다.
    itertools.islice(iterable, s.start, s.stop, s.step)
    

    (Raymond Hettinger 작성.)

  • locale 모듈의 format() 함수가 수정되었으며, 두 개의 새로운 함수인 :func:`format_string`과 :func:`currency`가 추가되었습니다.

    format() 함수의 val 매개변수는 이전에 하나 이상의 %char 지정자가 나타나지 않는 한 문자열일 수 있었지만, 이제 이 매개변수는 주변 텍스트 없이 정확히 하나의 %char 지정자여야 합니다. 또한 선택적인 monetary 매개변수도 추가되었는데, 이것이 True 이면 지역화 규칙을 사용하여 세 그룹 사이에 구분 기호를 배치하는 방식으로 통화를 포매팅하게 됩니다.

    여러 %char 지정자를 가진 문자열을 포맷하려면, format`과 유사하지만 임의의 텍스트와 %char 지정자를 혼합하여 지원하는 새로운 :func:`format_string() 함수를 사용하십시오.

    현재 로케일 설정에 따라 숫자를 포맷하는 새로운 currency() 함수도 추가되었습니다.

    (Georg Brandl 기여.)

  • mailbox 모듈은 메시지를 읽는 기능 외에도 메일박스를 수정할 수 있는 기능을 추가하기 위해 대규모로 재작성되었습니다. mbox, MH, 및 Maildir`를 포함하는 새로운 클래스 세트는 메일박스를 읽는 사용되며, 메시지 추가를 위한 ``add(message)` 메서드, 메시지 제거를 위한 remove(key), 그리고 메일박스 잠금/잠금 해제를 위한 lock()/:meth:`unlock`을 가지고 있습니다. 다음 예제는 maildir 형식의 메일박스를 mbox 형식으로 변환합니다:

    import mailbox
    
    # 'factory=None' 은 개별 메시지를 나타내는 클래스로 email.Message.Message를 사용합니다.
    src = mailbox.Maildir('maildir', factory=None)
    dest = mailbox.mbox('/tmp/mbox')
    
    for msg in src:
        dest.add(msg)
    

    (Gregory K. Johnson 기여. Google의 2005년 Summer of Code 지원.)

  • 새 모듈: msilib 모듈은 Microsoft Installer .msi 파일 및 CAB 파일을 생성할 수 있게 합니다. .msi 데이터베이스를 읽는 일부 지원도 포함되어 있습니다. (Martin von Löwis 기여.)

  • nis 모듈은 이제 nis.match()nis.maps() 함수에 domain 인수를 제공하여 시스템 기본 도메인이 아닌 다른 도메소리 접근을 지원합니다. (Ben Bell 기여.)

  • operator 모듈의 itemgetter()attrgetter() 함수는 이제 여러 필드를 지원합니다. operator.attrgetter('a', 'b')``와 같은 호출은 :attr:`a`와 :attr:`b` 속성을 검색하는 함수를 반환할 것입니다. 새로운 기능을 :meth:`sort` 메서드의 ``key 매개변수와 결합하면 여러 필드를 사용하여 목록을 쉽게 정렬할 수 있습니다. (Raymond Hettinger 기여.)

  • optparse 모듈은 Optik 라이브러리의 버전 1.5.1로 업데이트되었습니다. OptionParser 클래스는 help 메시지가 출력된 후 문자열인 epilog 속성과 객체가 만든 참조 사이클을 끊는 데 사용되는 destroy() 메서드를 갖게 되었습니다. (Greg Ward 기여.)

  • os 모듈은 여러 변경을 거쳤습니다. stat_float_times 변수는 이제 기본값이 true이므로, :func:`os.stat`은 이제 시간 값을 float으로 반환하게 됩니다. (이는 :func:`os.stat`이 초의 분수까지 정확한 시간을 반환한다는 것을 의미하지는 않습니다. 모든 시스템이 그러한 정밀도를 지원하는 것은 아닙니다.)

    os.SEEK_SET, os.SEEK_CUR, 및 os.SEEK_END`라는 이름의 상수가 추가되었으며, 이들은 :func:`os.lseek 함수의 매개변수입니다. 잠금용 두 개의 새로운 상수인 :const:`os.O_SHLOCK`와 :const:`os.O_EXLOCK`이 있습니다.

    두 개의 새로운 함수, wait3()wait4() 가 추가되었습니다. 이들은 자식 프로세스가 종료되기를 기다리고 해당 프로세스 ID와 종료 상태를 포함하는 튜플을 반환하는 waitpid() 함수와 유사하지만, wait3()wait4() 는 추가적인 정보를 반환합니다. wait3() 은 프로세스 ID를 입력으로 받지 않으므로 모든 자식 프로세스가 종료되기를 기다리고 resource.getrusage() 함수에서 반환되는 process-id, exit-status, resource-usage 의 3개 튜플을 반환합니다. wait4(pid) 는 프로세스 ID를 받습니다. (Chad J. Schroeder 기여.)

    FreeBSD에서, os.stat() 함수는 이제 나노초 해상도로 시간을 반환하며, 반환된 객체에는 st_genst_birthtime`이 추가되었습니다. 플랫폼이 지원하면 :attr:`st_flags 속성도 사용할 수 있습니다. (Antti Louko와 Diego Pettenò 기여.)

  • pdb 모듈에서 제공하는 Python 디버거는 이제 중단점이 도달하여 실행이 멈출 때 실행할 명령어 목록을 저장할 수 있습니다. 중단점 #1이 생성된 후, commands 1 을 입력하고 실행할 일련의 명령어를 입력한 다음 구문을 end 로 마무리합니다. 명령어 목록에는 continuenext 와 같이 실행을 재개하는 명령어가 포함될 수 있습니다. (Grégoire Dooms 기여.)

  • picklecPickle 모듈에서는 더 이상 __reduce__() 메서드가 None 을 반환하는 것을 허용하지 않습니다. 해당 메서드는 대신 인자들의 튜플을 반환해야 합니다. None 을 반환할 수 있는 기능은 Python 2.4에서 폐지되었으므로, 이번에 이 기능의 제거가 완료되었습니다.

  • pkgutil 모듈은 패키지를 찾는 다양한 유틸리티 함수를 포함하고 있으며, :pep:`302`의 임포트 훅을 지원하도록 개선되었고 이제 ZIP 형식 아카이브에 저장된 패키지에 대해서도 작동합니다. (Phillip J. Eby 기여.)

  • Marc-André Lemburg이 제작한 pybench 벤치마크 스위트가 이제 Tools/pybench 디렉터리에 포함되었습니다. pybench 스위트는 일반적으로 사용되는 pystone.py 프로그램보다 향상된 점을 제공합니다. 왜냐하면 pybench가 인터프리터의 속도를 더 상세하게 측정하기 때문입니다. 이 프로그램은 함수 호출, 튜플 슬라이싱, 메서드 조회 및 숫자 연산과 같은 특정 작업을 시간 기록하며, 여러 다른 작업을 수행하여 결과를 단일 숫자로 줄이는 :file:`pystone.py`와 다릅니다.

  • pyexpat 모듈은 이제 Expat 파서의 2.0 버전을 사용합니다. (Trent Mick 기여.)

  • Queue 모듈에서 제공하는 Queue 클래스가 두 가지 새로운 메서드를 얻었습니다. :meth:`join`은 큐의 모든 항목을 검색하여 해당 항목에 대한 모든 처리 작업이 완료될 때까지 대기합니다. 워커 스레드는 다른 새로운 메서드인 :meth:`task_done`을 호출하여 특정 항목의 처리가 완료되었음을 알립니다. (Raymond Hettinger 기여.)

  • 오래된 regexregsub 모듈은 Python 2.0 이후로 폐기되어 왔으며, 마침내 삭제되었습니다. 다른 삭제된 모듈: statcache, tzparse, whrandom.

  • 또한 다음이 삭제되었습니다: 오래된 모듈인 dircmpni 를 포함하는 lib-old 디렉터리입니다. lib-old 는 기본 sys.path 에 있었던 것이 아니므로, 프로그램에서 이 디렉터리를 명시적으로 sys.path 에 추가하지 않는 한, 이 제거는 코드에 영향을 미치지 않을 것입니다.

  • rlcompleter 모듈은 더 이상 readline 모듈을 임포트하는 것에 의존하지 않으며, 따라서 이제 비(非) Unix 플랫폼에서도 작동합니다. (Robert Kiendl 패치.)

  • SimpleXMLRPCServerDocXMLRPCServer 클래스는 이제 rpc_paths 속성을 갖게 되어 XML-RPC 작업을 제한된 URL 경로 세트로 제약합니다. 기본값은 '/'``과 ``'/RPC2'``만 허용하는 것입니다. :attr:`rpc_paths`를 ``None 또는 빈 튜플로 설정하면 이 경로 검사가 비활성화됩니다.

  • socket 모듈은 Philippe Biondi의 패치 덕분에 이제 리눅스에서 AF_NETLINK 소켓을 지원합니다. Netlink 소켓은 사용자 영역 프로세스와 커널 코드 간의 통신을 위한 리눅스 특정 메커니즘입니다. 이에 대한 입문 기사는 https://www.linuxjournal.com/article/7356에 있습니다. Python 코드에서 netlink 주소는 2개의 정수로 이루어진 튜플인 (pid, group_mask) 으로 표현됩니다.

    두 가지 새로운 소켓 객체 메서드인 recv_into(buffer)recvfrom_into(buffer) 는 수신된 데이터를 문자열로 반환하는 대신, 버퍼 프로토콜을 지원하는 객체에 저장합니다. 이는 데이터를 배열이나 메모리 매핑 파일에 직접 넣을 수 있음을 의미합니다.

    소켓 객체는 또한 getfamily(), gettype(), 그리고 getproto() 접근자 메서드를 얻어 소켓의 패밀리, 타입, 프로토콜 값을 검색할 수 있습니다.

  • 새 모듈: spwd 모듈은 섀도 암호를 지원하는 시스템에서 섀도 비밀번호 데이터베이스에 액세스하기 위한 함수를 제공합니다.

  • struct`는 이제 :meth:`packunpack() 메서드를 통해 포맷 문자열을 Struct 객체로 컴파일하기 때문에 더 빠릅니다. 이는 re 모듈이 컴파일된 정규 표현식 객체를 생성하는 방식과 유사합니다. 여전히 모듈 수준의 pack()unpack() 함수를 사용할 수 있으며, 이들은 Struct 객체를 생성하고 캐시합니다. 또는 다음과 같이 Struct 인스턴스를 직접 사용할 수도 있습니다:

    s = struct.Struct('ih3s')
    
    data = s.pack(1972, 187, 'abc')
    year, number, name = s.unpack(data)
    

    또한 pack_into(buffer, offset, v1, v2, ...)``와 ``unpack_from(buffer, offset) 메서드를 사용하면 버퍼 객체에 직접 데이터를 패킹하고 언패킹할 수 있습니다. 이를 통해 배열이나 메모리 맵 파일에 데이터를 직접 저장할 수 있습니다.

    Struct 객체는 Bob Ippolito가 NeedForSpeed 스프린트에서 구현했습니다. 버퍼 객체 지원은 Martin Blais가 또한 NeedForSpeed 스프린트에서 추가했습니다.

  • 파이썬 개발자들은 2.5 개발 과정 동안 CVS에서 Subversion으로 전환했습니다. 정확한 빌드 버전에 대한 정보는 sys.subversion 변수로 제공되며, 이는 (인터프리터 이름, 브랜치 이름, 개정 범위) 의 3-튜플입니다. 예를 들어, 작성 시점의 제 2.5 버전 사본은 ('CPython', 'trunk', '45313:45315') 를 보고하고 있었습니다.

    이 정보는 또한 Py_GetBuildInfo() 함수를 통해 C 확장에서도 사용할 수 있으며, 이 함수는 다음과 같은 빌드 정보를 담은 문자열을 반환합니다: "trunk:45355:45356M, Apr 13 2006, 07:42:19". (Barry Warsaw가 기여했습니다.)

  • 또 다른 새 함수인 :func:`sys._current_frames`는 실행 중인 모든 스레드의 현재 스택 프레임을 해당 함수가 호출되는 시점에 그 스레드에서 현재 활성화된 최상위 스택 프레임에 매핑하는 딕셔너리로 반환합니다. (Tim Peters가 기여했습니다.)

  • tarfile 모듈의 TarFile 클래스는 이제 아카이브의 모든 멤버를 현재 작업 디렉터리로 추출하는 extractall() 메서드를 갖게 되었습니다. 또한 다른 디렉터리를 추출 대상으로 설정하거나, 아카이브 멤버의 일부만을 언패킹하는 것도 가능합니다.

    스트림 모드로 열린 tarfile에 사용되는 압축은 이제 모드 'r|*' 를 사용하여 자동 감지할 수 있습니다. (Lars Gustäbel이 기여했습니다.)

  • threading 모듈을 사용하면 새로운 스레드가 생성될 때 사용되는 스택 크기를 설정할 수 있습니다. stack_size([*size*]) 함수는 현재 구성된 스택 크기를 반환하며, 선택적 size 매개변수를 제공하면 새 값을 설정합니다. 모든 플랫폼에서 스택 크기 변경을 지원하는 것은 아니지만, Windows, POSIX 스레딩, OS/2 모두 지원합니다. (Andrew MacIntyre가 기여했습니다.)

  • unicodedata 모듈이 유니코드 문자 데이터베이스의 버전 4.1.0을 사용하도록 업데이트되었습니다. 일부 사양에서는 버전 3.2.0이 필요하므로, 여전히 :data:`unicodedata.ucd_3_2_0`으로 사용할 수 있습니다.

  • 새 모듈: uuid 모듈은 RFC 4122 에 따라 범용 고유 식별자(UUID)를 생성합니다. 해당 RFC는 시작 문자열, 시스템 속성 또는 순전히 임의로 생성되는 여러 다른 버전의 UUID를 정의합니다. 이 모듈은 UUID 클래스와 다양한 버전의 UUID를 생성하기 위한 uuid1(), uuid3(), uuid4(), 및 uuid5() 라는 이름의 함수를 포함하고 있습니다. (버전 2 UUID는 RFC 4122 에 지정되어 있지 않으며 이 모듈에서 지원하지 않습니다.)

    >>> import uuid
    >>> # 호스트 ID 및 현재 시간을 기반으로 UUID 만들기
    >>> uuid.uuid1()
    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
    
    >>> # 네임스페이스 UUID와 이름의 MD5 해시를 사용하여 UUID 만들기
    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
    
    >>> # 임의의 UUID 만들기
    >>> uuid.uuid4()
    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
    
    >>> # 네임스페이스 UUID와 이름의 SHA-1 해시를 사용하여 UUID 만들기
    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
    

    (Ka-Ping Yee가 기여했습니다.)

  • weakref 모듈의 WeakKeyDictionaryWeakValueDictionary 타입은 딕셔너리에 포함된 약한 참조를 반복하는 새로운 메서드를 갖게 되었습니다. WeakKeyDictionary`에 :meth:`iterkeyrefs`와 :meth:`keyrefs 메서드가, 그리고 :class:`WeakValueDictionary`에 :meth:`itervaluerefs`와 :meth:`valuerefs`가 추가되었습니다. (Fred L. Drake, Jr.가 기여했습니다.)

  • The webbrowser module received a number of enhancements. It’s now usable as a script with python -m webbrowser, taking a URL as the argument; there are a number of switches to control the behaviour (-n for a new browser window, -t for a new tab). New module-level functions, open_new() and open_new_tab(), were added to support this. The module’s open() function supports an additional feature, an autoraise parameter that signals whether to raise the open window when possible. A number of additional browsers were added to the supported list such as Firefox, Opera, Konqueror, and elinks. (Contributed by Oleg Broytmann and Georg Brandl.)

  • xmlrpclib 모듈은 이제 XML-RPC 날짜 유형의 datetime 객체를 반환하는 것을 지원합니다. 이 기능을 활성화하려면 loads() 함수나 Unmarshaller 클래스에 `use_datetime=True`를 제공하십시오. (Skip Montanaro 기여)

  • zipfile 모듈은 이제 ZIP64 버전의 형식을 지원합니다. 이는 .zip 아카이브의 크기가 4 GiB를 초과할 수 있으며, 4 GiB를 초과하는 개별 파일도 포함할 수 있음을 의미합니다. (Ronald Oussoren 기여)

  • zlib 모듈의 Compress`와 :class:`Decompress 객체가 이제 내부 상태를 복사하는 copy() 메서드를 지원하며, 새로운 Compress 또는 Decompress 객체를 반환합니다. (Chris AtLee 기여)

ctypes 패키지

ctypes 패키지는 Thomas Heller가 작성했으며, 표준 라이브러리에 추가되었습니다. ctypes`는 공유 라이브러리나 DLL에 있는 임의 함수를 호출할 있도록 해줍니다. 오랜 사용자들은 공유 라이브러리를 로드하고 안에 있는 함수들을 호출하는 기능을 제공하는 :mod:!dl` 모듈을 기억할 수도 있습니다. 그러나 ctypes 패키지는 훨씬 더 개선되었습니다.

공유 라이브러리나 DLL을 로드하려면, 먼저 CDLL 클래스의 인스턴스를 생성하고 공유 라이브러리 또는 DLL의 이름이나 경로를 제공해야 합니다. 그런 다음 CDLL 객체의 속성으로 접근하여 임의 함수들을 호출할 수 있습니다.

import ctypes

libc = ctypes.CDLL('libc.so.6')
result = libc.printf("Line of output\n")

Type constructors for the various C types are provided: c_int(), c_float(), c_double(), c_char_p() (equivalent to char*), and so forth. Unlike Python’s types, the C versions are all mutable; you can assign to their value attribute to change the wrapped value. Python integers and strings will be automatically converted to the corresponding C types, but for other types you must call the correct type constructor. (And I mean must; getting it wrong will often result in the interpreter crashing with a segmentation fault.)

You shouldn’t use c_char_p() with a Python string when the C function will be modifying the memory area, because Python strings are supposed to be immutable; breaking this rule will cause puzzling bugs. When you need a modifiable memory area, use create_string_buffer():

s = "this is a string"
buf = ctypes.create_string_buffer(s)
libc.strfry(buf)

C functions are assumed to return integers, but you can set the restype attribute of the function object to change this:

>>> libc.atof('2.71828')
-1783957616
>>> libc.atof.restype = ctypes.c_double
>>> libc.atof('2.71828')
2.71828

ctypes also provides a wrapper for Python’s C API as the ctypes.pythonapi object. This object does not release the global interpreter lock before calling a function, because the lock must be held when calling into the interpreter’s code. There’s a py_object type constructor that will create a PyObject* pointer. A simple usage:

import ctypes

d = {}
ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),
          ctypes.py_object("abc"),  ctypes.py_object(1))
# d is now {'abc', 1}.

Don’t forget to use py_object(); if it’s omitted you end up with a segmentation fault.

:mod:`ctypes`는 오랫동안 사용되어 온 모듈이지만, :mod:`ctypes`의 존재를 신뢰할 수 없기 때문에 개발자들이 여전히 외부에서 코딩된 확장 모듈을 작성하고 배포합니다. 이제 :mod:`ctypes`가 핵심 Python에 포함됨에 따라, 개발자들은 대신 :mod:`ctypes`를 통해 접근하는 라이브러리 위에 순수 Python 래퍼를 작성하기 시작할지도 모릅니다.

더 보기

https://web.archive.org/web/20180410025338/http://starship.python.net/crew/theller/ctypes/

전처리를 거친 ctypes 웹 페이지로, 튜토리얼, 레퍼런스 및 FAQ가 포함되어 있습니다.

ctypes 모듈에 대한 문서입니다.

ElementTree 패키지

Fredrik Lundh의 ElementTree 라이브러리의 일부가 xml.etree`로 표준 라이브러리에 추가되었습니다. 사용 가능한 모듈은 ElementTree 1.2.6의 :mod:`ElementTree, ElementPath, 그리고 ElementInclude`입니다. 또한, :mod:`cElementTree 가속기 모듈도 포함되어 있습니다.

이 섹션의 나머지는 ElementTree 사용에 대한 간단한 개요를 제공할 것입니다. ElementTree에 대한 전체 문서는 https://web.archive.org/web/20201124024954/http://effbot.org/zone/element-index.htm 에서 확인할 수 있습니다.

ElementTree는 XML 문서를 엘리먼트 노드의 트리로 나타냅니다. 문서의 텍스트 콘텐츠는 texttail 어트리뷰트로 저장됩니다 (이는 ElementTree와 Document Object Model 사이의 주요 차이점 중 하나입니다. DOM에는 :class:`TextNode`를 포함하여 다양한 유형의 노드가 있습니다).

가장 일반적으로 사용되는 구문 분석 함수는 parse`이며, 문자열(파일 이름을 포함한다고 가정함) 또는 파일 유사 객체를 인수로 받아 :class:`ElementTree() 인스턴스를 반환합니다:

from xml.etree import ElementTree as ET

tree = ET.parse('ex-1.xml')

feed = urllib.urlopen(
          'http://planet.python.org/rss10.xml')
tree = ET.parse(feed)

ElementTree 인스턴스를 얻었다면, 그 getroot() 메서드를 호출하여 루트 Element 노드를 가져올 수 있습니다.

문자열 리터럴을 받아 Element 노드( ElementTree`는 아님)를 반환하는 :func:`XML 함수도 있습니다. 이 함수는 XML 조각들을 깔끔하게 포함할 수 있는 방법을 제공하여 XML 리터럴의 편리함에 가깝습니다:

svg = ET.XML("""<svg width="10px" version="1.0">
             </svg>""")
svg.set('height', '320px')
svg.append(elem1)

각 XML 엘리먼트는 딕셔너리 유사 접근 및 목록 유사 접근 메서드를 지원합니다. 딕셔너리 유사 작업은 어트리뷰트 값을 액세스하는 데 사용되며, 목록 유사 작업은 자식 노드에 액세스하는 데 사용됩니다.

연산

결과

elem[n]

n번째 자식 엘리먼트를 반환합니다.

elem[m:n]

m번째부터 n번째까지의 자식 엘리먼트 목록을 반환합니다.

len(elem)

자식 엘리먼트 수를 반환합니다.

list(elem)

자식 엘리먼트 목록을 반환합니다.

elem.append(elem2)

elem2 를 자식으로 추가합니다.

elem.insert(index, elem2)

지정된 위치에 elem2 를 삽입합니다.

del elem[n]

n번째 자식 엘리먼트를 삭제합니다.

elem.keys()

어트리뷰트 이름 목록을 반환합니다.

elem.get(name)

어트리뷰트 name 의 값을 반환합니다.

elem.set(name, value)

어트리뷰트 name 에 새 값을 설정합니다.

elem.attrib

어트리뷰트를 포함하는 딕셔너리를 검색합니다.

del elem.attrib[name]

name 어트리뷰트를 삭제합니다.

주석과 처리 지시문도 Element 노드로 표현됩니다. 노드가 주석인지 아니면 처리 지시문인지 확인하려면:

if elem.tag is ET.Comment:
    ...
elif elem.tag is ET.ProcessingInstruction:
    ...

XML 출력을 생성하려면 ElementTree.write() 메서드를 호출해야 합니다. :func:`parse`와 마찬가지로 문자열 또는 파일 유사 객체를 인수로 받을 수 있습니다:

# 인코딩은 US-ASCII입니다.
tree.write('output.xml')

# 인코딩은 UTF-8입니다.
f = open('output.xml', 'w')
tree.write(f, encoding='utf-8')

(주의: 출력에 사용되는 기본 인코딩은 ASCII입니다. 요소 이름에 임의의 유니코드 문자가 포함될 수 있는 일반적인 XML 작업의 경우, ASCII는 안전하지 않은 인코딩입니다. 이는 요소 이름이 127보다 큰 값을 가진 문자를 포함하면 예외를 발생시키기 때문입니다. 따라서 모든 유니코드 문자를 처리할 수 있는 다른 인코딩(예: UTF-8)을 지정하는 것이 가장 좋습니다.)

이 섹션은 ElementTree 인터페이스에 대한 부분적인 설명만을 담고 있습니다. 더 자세한 내용은 패키지의 공식 문서를 참조하십시오.

hashlib 패키지

Gregory P. Smith가 작성한 새로운 hashlib 모듈이 md5sha 모듈을 대체하기 위해 추가되었습니다. :mod:`hashlib`은 추가적인 하드웨어 보안 해시(SHA-224, SHA-256, SHA-384, 및 SHA-512)를 지원합니다. 모듈은 사용 가능한 경우 알고리즘의 빠르고 플랫폼에 최적화된 구현을 위해 OpenSSL을 사용합니다.

이전의 md5sha 모듈은 하위 호환성을 유지하기 위한 hashlib의 래퍼로 여전히 존재합니다. 새 모듈의 인터페이스는 이전 모듈과 매우 유사하지만 동일하지는 않습니다. 가장 중요한 차이점은 새로운 해싱 객체를 생성하기 위한 생성자 함수 이름이 다르다는 것입니다.

# 구형 버전들
h = md5.md5()
h = md5.new()

# 신규 버전
h = hashlib.md5()

# 구형 버전들
h = sha.sha()
h = sha.new()

# 신규 버전
h = hashlib.sha1()

# 이전에 제공되지 않았던 해시
h = hashlib.sha224()
h = hashlib.sha256()
h = hashlib.sha384()
h = hashlib.sha512()

# 대체 형태
h = hashlib.new('md5')          # 알고리즘을 문자열로 제공

해시 객체를 생성하면, 그 메서드는 이전과 동일합니다: update(string) 는 지정된 문자열을 현재 다이제스트 상태로 해싱하고, digest()hexdigest() 는 다이제스트 값을 바이너리 문자열이나 16진수 문자열로 반환하며, copy() 는 동일한 다이제스트 상태를 가진 새로운 해싱 객체를 반환합니다.

더 보기

hashlib 모듈에 대한 설명서입니다.

sqlite3 패키지

pysqlite 모듈(https://www.pysqlite.org)은 SQLite 임베디드 데이터베이스의 래퍼이며, 표준 라이브러리에 sqlite3 패키지 이름으로 추가되었습니다.

SQLite는 별도의 서버 프로세스가 필요하지 않은 경량 디스크 기반 데이터베이스를 제공하는 C 라이브러리이며, 비표준 SQL 쿼리 언어 변형을 사용하여 데이터베이스에 액세스할 수 있게 합니다. 일부 애플리케이션은 내부 데이터 저장용으로 SQLite를 사용할 수 있습니다. SQLite를 사용하여 애플리케이션을 프로토타이핑한 다음, 코드를 PostgreSQL 또는 Oracle과 같은 더 큰 데이터베이스로 이식하는 것도 가능합니다.

pysqlite는 Gerhard Häring이 작성했으며 :pep:`249`에서 설명된 DB-API 2.0 사양을 준수하는 SQL 인터페이스를 제공합니다.

파이썬 소스 코드를 직접 컴파일하는 경우, 소스 트리에 SQLite 코드는 포함되어 있지 않고 래퍼 모듈만 포함되어 있다는 점에 유의하십시오. 파이썬을 컴파일하기 전에 SQLite 라이브러리와 헤더가 설치되어 있어야 하며, 빌드 과정에서 필요한 헤더가 사용 가능할 때 모듈이 컴파일됩니다.

모듈을 사용하려면, 먼저 데이터베이스를 나타내는 Connection 객체를 생성해야 합니다. 여기에 데이터는 /tmp/example 파일에 저장될 것입니다:

conn = sqlite3.connect('/tmp/example')

You can also supply the special name :memory: to create a database in RAM.

Connection 객체를 얻었다면, Cursor 객체를 만들고 그 execute() 메서드를 호출하여 SQL 명령을 수행할 수 있습니다:

c = conn.cursor()

# 테이블 생성
c.execute('''create table stocks
(date text, trans text, symbol text,
 qty real, price real)''')

# 데이터 행 삽입
c.execute("""insert into stocks
          values ('2006-01-05','BUY','RHAT',100,35.14)""")

일반적으로 SQL 연산은 파이썬 변수의 값을 사용해야 합니다. 파이썬의 문자열 연산을 사용하여 질의를 조합해서는 안 됩니다. 그렇게 하는 것은 안전하지 않으며, 프로그램이 SQL 인젝션 공격에 취약하게 만듭니다.

대신 DB-API에서 제공하는 매개변수 치환 기능을 사용하십시오. 값을 사용하려는 곳마다 ? 를 자리 표시자로 넣고, 커서의 execute() 메서드에 두 번째 인수로 값 튜플을 제공하면 됩니다. (다른 데이터베이스 모듈은 %s 또는 :1 와 같은 다른 자리 표시자를 사용할 수 있습니다.) 예를 들면 다음과 같습니다:

# 절대 이렇게 하지 마세요 -- 안전하지 않습니다!
symbol = 'IBM'
c.execute("... where symbol = '%s'" % symbol)

# 대신 이걸 사용하세요
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)

# 더 큰 예시
for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
          ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
          ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
         ):
    c.execute('insert into stocks values (?,?,?,?,?)', t)

To retrieve data after executing a SELECT statement, you can either treat the cursor as an iterator, call the cursor’s fetchone() method to retrieve a single matching row, or call fetchall() to get a list of the matching rows.

이 예제는 이터레이터 형태를 사용합니다:

>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
...    print row
...
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>

SQLite에서 지원되는 SQL 방언에 대한 자세한 내용은 https://www.sqlite.org를 참조하십시오.

더 보기

https://www.pysqlite.org

pysqlite 웹 페이지입니다.

https://www.sqlite.org

SQLite 웹 페이지; 설명서에서는 지원되는 SQL 방언에 대한 문법 및 사용 가능한 데이터 유형을 설명합니다.

sqlite3 모듈에 대한 설명서입니다.

PEP 249 - 데이터베이스 API 사양 2.0

Marc-André Lemburg가 작성한 PEP입니다.

wsgiref 패키지

Web Server Gateway Interface (WSGI) v1.0은 웹 서버와 Python 웹 애플리케이션 간의 표준 인터페이스를 정의하며 PEP 333 에 설명되어 있습니다. wsgiref 패키지는 WSGI 사양의 참고 구현입니다.

이 패키지에는 WSGI 애플리케이션을 실행하는 기본 HTTP 서버가 포함되어 있습니다. 이 서버는 디버깅에 유용하지만, 프로덕션 사용용은 아닙니다. 서버 설정은 몇 줄의 코드로 충분합니다:

from wsgiref import simple_server

wsgi_app = ...

host = ''
port = 8000
httpd = simple_server.make_server(host, port, wsgi_app)
httpd.serve_forever()

더 보기

https://web.archive.org/web/20160331090247/http://wsgi.readthedocs.org/en/latest/

WSGI 관련 리소스를 위한 중앙 웹 사이트입니다.

PEP 333 - Python Web Server Gateway Interface v1.0

Phillip J. Eby가 작성한 PEP.

빌드 및 C API 변경사항

파이썬의 빌드 프로세스와 C API에 대한 변경 사항은 다음과 같습니다:

  • Python 소스 트리는 CVS에서 Subversion으로 변환되었으며, 이는 Martin von Löwis가 감독하고 완벽하게 수행한 복잡한 마이그레이션 절차였습니다. 이 절차는 :pep:`347`로 개발되었습니다.

  • Coverity라는 회사(Prevent라는 소스 코드 분석 도구를 판매)가 Python 소스 코드를 검사한 결과를 제공했습니다. 이 분석을 통해 약 60개의 버그를 발견하여 빠르게 수정되었습니다. 많은 버그는 특히 오류 처리 코드에서 발생하는 참조 카운트 문제였습니다. 통계는 https://scan.coverity.com에서 확인하십시오.

  • C API에 대한 가장 큰 변경 사항은 PEP 353 에서 발생했습니다. 이는 인터프리터를 Py_ssize_t 타입 정의를 사용하도록 수정하여 (기존 int 대신) 합니다. 이 변경 사항에 대한 논의는 이전 섹션인 PEP 353: 인덱스 유형으로 ssize_t 사용하기 를 참조하십시오.

  • 바이트코드 컴파일러의 설계가 크게 바뀌어, 더 이상 파싱 트리를 순회하며 바이트코드를 생성하지 않습니다. 대신 파싱 트리가 추상 구문 트리(AST)로 변환되며, 이 AST를 순회하여 바이트코드가 생성됩니다.

    compile() 내장 함수를 사용하고 flags 매개변수 값으로 _ast.PyCF_ONLY_AST 를 지정하면 Python 코드를 AST 객체로 얻는 것이 가능합니다:

    from _ast import PyCF_ONLY_AST
    ast = compile("""a=0
    for i in range(10):
        a += i
    """, "<string>", 'exec', PyCF_ONLY_AST)
    
    assignment = ast.body[0]
    for_loop = ast.body[1]
    

    아직 AST 코드에 대한 공식 문서는 작성되지 않았지만, PEP 339 에서 설계가 논의됩니다. 이 코드를 학습하려면 Parser/Python.asdl 에 있는 다양한 AST 노드 정의를 읽으십시오. Python 스크립트가 이 파일을 읽어 Include/Python-ast.h 에 C 구조체 정의 세트를 생성합니다. PyParser_ASTFromString()PyParser_ASTFromFile()Include/pythonrun.h 에 정의되어 있으며, Python 소스를 입력으로 받아 내용의 루트 AST를 반환합니다. 이 AST는 PyAST_Compile() 을 사용해 코드 객체로 변환될 수 있습니다. 더 자세한 정보가 필요하면 소스 코드를 읽고 python-dev에서 질문하십시오.

    AST 코드는 Jeremy Hylton의 관리 하에 개발되었으며, (알파벳 순서로) Brett Cannon, Nick Coghlan, Grant Edwards, John Ehresman, Kurt Kaiser, Neal Norwitz, Tim Peters, Armin Rigo, 그리고 PyCon과 같은 컨퍼런스에서 열린 여러 AST 스프린트를 참여한 분들에 의해 구현되었습니다.

  • PyCon DC 2005 발표에서 처음 설명된 Evan Jones의 obmalloc 패치가 적용되었습니다. Python 2.4는 작은 객체를 256K 크기의 아레나에 할당했지만, 아레나는 절대 해제하지 않았습니다. 이 패치를 통해 Python은 아레나가 비어 있을 때 해제합니다. 그 결과, 일부 플랫폼에서 많은 객체를 할당하고 삭제하면 메모리 사용량이 실제로 감소할 수 있으며, 메모리가 운영 체제에 반환될 수 있습니다. (Evan Jones가 구현했으며 Tim Peters가 수정했습니다.)

    이 변경 사항은 확장 모듈이 메모리 할당 시 더 주의해야 함을 의미한다는 점에 유의하십시오. Python API에는 가족으로 그룹화된 여러 가지 메모리 할당 함수가 있습니다. 예를 들어, PyMem_Malloc(), PyMem_Realloc(), 및 PyMem_Free() 는 원시 메모리를 할당하는 하나의 계열이고, PyObject_Malloc(), PyObject_Realloc(), 및 PyObject_Free() 는 Python 객체 생성에 사용되어야 하는 또 다른 계열입니다.

    이전에 이러한 다른 패밀리들은 모두 플랫폼의 malloc()free() 함수로 축소되었습니다. 이 말은 문제가 있어도 PyMem 함수를 사용하여 메모리를 할당하고 PyObject 함수로 해제하는 등 간섭해도 상관없었다는 뜻이었습니다. obmalloc의 2.5 버전 변경 사항으로 인해, 이러한 패밀리들은 이제 서로 다른 작업을 수행하며 불일치할 경우 아마도 세그폴트가 발생할 것입니다. Python 2.5를 사용하여 C 확장 모듈을 주의 깊게 테스트해야 합니다.

  • 내장 set 타입에는 이제 공식 C API가 있습니다. PySet_New() 및 :c:func:`PyFrozenSet_New`를 호출하여 새 set을 만들고, :c:func:`PySet_Add`와 :c:func:`PySet_Discard`를 사용하여 요소를 추가 및 제거하며, :c:func:`PySet_Contains`와 :c:func:`PySet_Size`를 사용하여 set의 상태를 검사할 수 있습니다. (Raymond Hettinger 기여)

  • C 코드는 이제 Py_GetBuildInfo() 함수를 호출하여 파이썬 인터프리터의 정확한 개정 버전에 대한 정보를 얻을 수 있으며, 이 문자열은 "trunk:45355:45356M, Apr 13 2006, 07:42:19" 와 같은 빌드 정보로 반환됩니다. (Barry Warsaw 기여)

  • Two new macros can be used to indicate C functions that are local to the current file so that a faster calling convention can be used. Py_LOCAL declares the function as returning a value of the specified type and uses a fast-calling qualifier. Py_LOCAL_INLINE does the same thing and also requests the function be inlined. If macro PY_LOCAL_AGGRESSIVE is defined before python.h is included, a set of more aggressive optimizations are enabled for the module; you should benchmark the results to find out if these optimizations actually make the code faster. (Contributed by Fredrik Lundh at the NeedForSpeed sprint.)

  • PyErr_NewException(name, base, dict) 는 이제 base 인자로 기본 클래스들의 튜플을 받을 수 있습니다. (Georg Brandl 기여)

  • 경고를 발생시키기 위한 PyErr_Warn() 함수는 이제 이 함수와 호출자를 구분하는 스택 프레임의 수를 지정할 수 있는 PyErr_WarnEx(category, message, stacklevel) 로 사용이 중단되었습니다. stacklevel 이 1인 경우 PyErr_WarnEx() 를 호출하는 함수이고, 2는 그 위의 함수이며, 계속됩니다. (Neal Norwitz 추가)

  • CPython 인터프리터 자체는 여전히 C로 작성되어 있지만, 이제 오류 없이 C++ 컴파일러로 컴파일할 수 있습니다. (Anthony Baxter, Martin von Löwis, Skip Montanaro 구현)

  • PyRange_New() 함수가 제거되었습니다. 이 함수는 문서화된 적이 없었고 핵심 코드에서도 사용되지 않았으며 위험할 정도로 느슨한 오류 검사를 가지고 있었습니다. 만약 사용자 모듈에서 이 함수를 사용하는 경우라면, 다음과 같은 방식으로 대체할 수 있습니다:

    range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll",
                                  start, stop, step);
    

플랫폼별 변경 사항

  • MacOS X (10.3 이상): 모듈의 동적 로딩은 이제 macOS 전용 함수 대신 dlopen() 함수를 사용합니다.

  • MacOS X: 해석기를 PowerPC 및 Intel 프로세서 모두에서 실행할 수 있는 범용 바이너리로 컴파일하는 configure 스크립트에 --enable-universalsdk 스위치가 추가되었습니다. (Ronald Oussoren 기여; bpo-2573)

  • Windows: 확장 모듈의 파일 이름 접미사로 더 이상 .dll`이 지원되지 않습니다. 이제 검색되는 유일한 파일 이름 접미사는 :file:.pyd`입니다.

Python 2.5로 이식하기

이 섹션은 코드 변경이 필요할 수 있는 이전에 설명된 변경 사항 목록을 담고 있습니다:

  • ASCII가 이제 모듈의 기본 인코딩입니다. 모듈에 8비트 문자를 가진 문자열 리터럴이 포함되어 있지만 인코딩 선언이 없는 경우 구문 오류가 발생합니다. Python 2.4에서는 경고만 발생했고, 구문 오류는 아니었습니다.

  • 이전에 제너레이터의 gi_frame 속성은 항상 프레임 객체였습니다. 하지만 섹션 PEP 342: 새로운 제너레이터 기능들 에 설명된 PEP 342 변경 사항 때문에, 이제 gi_frameNone 일 수 있게 되었습니다.

  • 새로운 경고인 UnicodeWarning`은 기본 ASCII 인코딩을 사용하여 유니코드 문자열과 변환할 없는 8비트 문자열을 비교하려고 시도할 발생합니다. 이전에 이러한 비교는 :class:`UnicodeDecodeError 예외를 발생시켰습니다.

  • 라이브러리: csv 모듈은 이제 다중 라인 따옴표 필드에 대해 더 엄격해졌습니다. 파일에 필드 내부에 개행 문자(newline)가 포함된 경우, 입력은 해당 개행 문자를 보존하는 방식으로 줄 단위로 분할되어야 합니다.

  • 라이브러리: locale 모듈의 format() 함수는 이전에 하나 이상의 %char 지정자가 나타나지 않는 한 모든 문자열을 허용했습니다. Python 2.5에서는 인수가 주변 텍스트 없이 정확히 하나의 %char 지정자여야 합니다.

  • 라이브러리: picklecPickle 모듈은 더 이상 __reduce__() 메서드에 대해 None 반환 값을 허용하지 않습니다. 대신 이 메서드는 인수 튜플을 반환해야 합니다. 또한 해당 모듈들은 이제 사용 중단된 bin 키워드 인수를 허용하지 않습니다.

  • 라이브러리: SimpleXMLRPCServerDocXMLRPCServer 클래스는 이제 XML-RPC 작업을 제한된 URL 경로 세트로 구속하는 rpc_paths 속성을 가집니다. 기본값은 '/'``와 ``'/RPC2'``만 허용합니다.  :attr:`rpc_paths`를 ``None 또는 빈 튜플로 설정하면 이 경로 검사가 비활성화됩니다.

  • C API: 많은 함수가 64비트 장치에서 더 많은 데이터를 처리할 수 있도록 Py_ssize_t 대신 :c:expr:`int`를 사용합니다. 확장은 경고를 방지하고 64비트 장치를 지원하기 위해 동일한 변경을 할 필요가 있을 수 있습니다. 이 변경에 대한 논의는 이전 섹션 :ref:`pep-353`을 참조하십시오.

  • C API: obmalloc 변경 사항은 PyMem_*PyObject_* 계열 함수 사용을 혼합하지 않도록 주의해야 한다는 것을 의미합니다. 한 계열의 *_Malloc``으로 할당된 메모리는 해당 계열의 ``*_Free 함수로 해제되어야 합니다.

감사의 말

필자는 이 글의 다양한 초안을 제안하고 수정하고 도와준 다음 사람들에게 감사드립니다: Georg Brandl, Nick Coghlan, Phillip J. Eby, Lars Gustäbel, Raymond Hettinger, Ralf W. Grosse-Kunstleve, Kent Johnson, Iain Lowe, Martin von Löwis, Fredrik Lundh, Andrew McNamara, Skip Montanaro, Gustavo Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott Weikart, Barry Warsaw, Thomas Wouters.

분실물 보관소