파이썬 3.2의 새로운 기능:¶
- 저자:
Raymond Hettinger
이 기사에서는 Python 3.1과 비교하여 Python 3.2의 새로운 기능을 설명합니다. Python 3.2는 2011년 2월 20일에 출시되었습니다. 몇 가지 주요 내용을 중점적으로 다루고 몇 가지 예시를 제공합니다. 자세한 내용은 `Misc/NEWS <https://github.com/python/cpython/blob/076ca6c3c8df3030307e548d9be792ce3c1c6eea/Misc/NEWS>` 파일을 참조하십시오.
더 보기
PEP 392 - Python 3.2 출시 일정
PEP 384: Defining a Stable ABI¶
In the past, extension modules built for one Python version were often not usable with other Python versions. Particularly on Windows, every feature release of Python required rebuilding all extension modules that one wanted to use. This requirement was the result of the free access to Python interpreter internals that extension modules could use.
Python 3.2 버전부터는 대안적인 접근 방식이 가능해졌습니다: 제한된 API(Py_LIMITED_API를 정의하여 제한하는 확장 모듈)의 경우 많은 내부 기능을 사용할 수는 없지만, 여러 버전에 안정적이라고 약속하는 일련의 API 함수로 제약됩니다. 그 결과, 해당 모드로 3.2용으로 빌드된 확장 모듈은 3.3, 3.4 등의 버전에서도 작동합니다. 메모리 구조의 세부 사항을 사용하는 확장 모듈도 여전히 빌드할 수 있지만, 모든 기능이 출시될 때마다 다시 컴파일해야 합니다.
더 보기
- PEP 384 - 안정적인 ABI 정의
Martin von Löwis가 작성한 PEP.
PEP 389: Argparse 명령행 파싱 모듈¶
명령행 파싱을 위한 새로운 모듈인 :mod:`argparse`가 소개되어, 위치 인자(옵션뿐만 아니라) 및 서브 커맨드, 필수 옵션 등 일반적인 패턴 지정 및 검증에서 :mod:`optparse`의 한계를 극복했습니다.
이 모듈은 이미 서드파티 모듈로서 커뮤니티에서 광범위하게 성공을 거두었습니다. 이전 버전보다 기능이 더 풍부해진 argparse 모듈은 이제 명령행 처리를 위한 권장되는 모듈입니다. 오래된 모듈은 여전히 그것에 의존하는 방대한 양의 레거시 코드 때문에 유지되고 있습니다.
다음 주석 처리된 예제 파서는 결과 범위를 선택 가능한 값으로 제한하거나, 도움말 화면에 메타 변수 지정, 하나 이상의 위치 인자가 존재하는지 검증하거나, 필수 옵션을 만드는 등의 기능을 보여줍니다:
import argparse
parser = argparse.ArgumentParser(
description = '서버 관리', # 도움말의 주 설명
epilog = 'Solaris 및 Linux에서 테스트됨') # 도움말 표시 후 출력
parser.add_argument('action', # 인자 이름
choices = ['deploy', 'start', 'stop'], # 허용되는 세 가지 값
help = '각 타겟에 대한 작업 유형') # 도움말 메시지
parser.add_argument('targets',
metavar = 'HOSTNAME', # 도움말 메시지에 사용되는 변수 이름
nargs = '+', # 하나 이상의 타겟을 요구함
help = '대상 기계의 URL') # 도움말 설명 메시지
parser.add_argument('-u', '--user', # -u 또는 --user 옵션
required = True, # 필수 인자로 지정
help = '사용자 계정으로 로그인')
명령 문자열을 파서에 전달하는 예시:
>>> cmd = 'deploy sneezy.example.com sleepy.example.com -u skycaptain'
>>> result = parser.parse_args(cmd.split())
>>> result.action
'deploy'
>>> result.targets
['sneezy.example.com', 'sleepy.example.com']
>>> result.user
'skycaptain'
파서가 자동으로 생성한 도움말 메시지 예시:
>>> parser.parse_args('-h'.split())
usage: manage_cloud.py [-h] -u USER
{deploy,start,stop} HOSTNAME [HOSTNAME ...]
Manage servers
positional arguments:
{deploy,start,stop} action on each target
HOSTNAME url for target machines
optional arguments:
-h, --help show this help message and exit
-u USER, --user USER login as user
Tested on Solaris and Linux
:mod:`argparse`의 매우 좋은 기능 중 하나는 자신의 인자 패턴 및 도움말 표시를 가진 서브 파서를 정의할 수 있다는 점입니다:
import argparse
parser = argparse.ArgumentParser(prog='HELM')
subparsers = parser.add_subparsers()
parser_l = subparsers.add_parser('launch', help='제어실 가동') # 첫 번째 서브 그룹
parser_l.add_argument('-m', '--missiles', action='store_true')
parser_l.add_argument('-t', '--torpedos', action='store_true')
parser_m = subparsers.add_parser('move', help='함선 이동', # 두 번째 서브 그룹
aliases=('steer', 'turn')) # 동등한 이름
parser_m.add_argument('-c', '--course', type=int, required=True)
parser_m.add_argument('-s', '--speed', type=int, default=0)
$ ./helm.py --help # 최상위 도움말 (launch 및 move)
$ ./helm.py launch --help # launch 옵션 도움말
$ ./helm.py launch --missiles # missiles=True, torpedos=False로 설정
$ ./helm.py steer --course 180 --speed 5 # 이동 매개변수 설정
PEP 391: 로깅을 위한 딕셔너리 기반 구성¶
logging 모듈은 옵션에 따라 함수 호출 방식의 구성과 `:mod:`configparser` 형식으로 저장된 외부 파일을 통해 설정하는 두 가지 유형의 구성을 제공했습니다. 하지만 이 옵션들은 JSON 또는 YAML 파일로부터 설정을 생성할 수 있는 유연성이 부족했고, 명령줄에서 로거 옵션을 지정하는 데 필요한 점진적 구성도 지원하지 않았습니다.
더 유연한 스타일을 지원하기 위해, 모듈은 이제 일반 Python 딕셔너리로 로깅 구성을 지정할 수 있는 :func:`logging.config.dictConfig`를 제공합니다. 구성 옵션에는 포매터, 핸들러, 필터 및 로거가 포함됩니다. 다음은 구성 딕셔너리의 작동 예제입니다:
{"version": 1,
"formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
"full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"}
},
"handlers": {"console": {
"class": "logging.StreamHandler",
"formatter": "brief",
"level": "INFO",
"stream": "ext://sys.stdout"},
"console_priority": {
"class": "logging.StreamHandler",
"formatter": "full",
"level": "ERROR",
"stream": "ext://sys.stderr"}
},
"root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
만약 해당 딕셔너리가 :file:`conf.json`이라는 파일에 저장되어 있다면, 다음과 같은 코드로 로드하고 사용할 수 있습니다:
>>> import json, logging.config
>>> with open('conf.json') as f:
... conf = json.load(f)
...
>>> logging.config.dictConfig(conf)
>>> logging.info("Transaction completed normally")
INFO : root : Transaction completed normally
>>> logging.critical("Abnormal termination")
2011-02-17 11:14:36,694 root CRITICAL Abnormal termination
더 보기
- PEP 391 - 로깅을 위한 딕셔너리 기반 구성
Vinay Sajip가 작성한 PEP.
PEP 3148: concurrent.futures 모듈¶
동시성 생성 및 관리에 대한 코드가 새로운 최상위 네임스페이스인 concurrent*에 수집되고 있습니다. 그 첫 번째 멤버는 스레드와 프로세스를 관리하기 위한 통일된 고수준 인터페이스를 제공하는 *futures 패키지입니다.
:mod:`concurrent.futures`에 대한 설계는 java.util.concurrent 패키지에서 영감을 받았습니다. 이 모델에서는 실행 중인 호출과 그 결과가 스레드, 프로세스 및 원격 프로시저 호출에 공통되는 기능을 추상화하는 Future 객체로 표현됩니다. 해당 객체는 상태 확인(실행 중 또는 완료), 시간 초과, 취소, 콜백 추가 및 결과/예외 접근을 지원합니다.
새 모듈의 주요 기능은 호출을 시작하고 관리하기 위한 두 쌍의 executor 클래스입니다. 이 executor들의 목표는 병렬 호출을 수행하는 기존 도구 사용을 더 쉽게 만드는 것입니다. 이를 통해 리소스 풀 설정, 호출 시작, 결과 큐 생성, 시간 초과 처리 추가 및 스레드, 프로세스 또는 원격 프로시저 호출의 총 개수 제한에 필요한 노력이 절약됩니다.
이상적으로는 각 애플리케이션이 여러 컴포넌트 전반에서 단일 executor를 공유해야 하므로, 프로세스 및 스레드 제한을 중앙 집중식으로 관리할 수 있습니다. 이는 각 컴포넌트가 자원 관리를 위한 자체 경쟁 전략을 가질 때 발생하는 설계상의 과제를 해결합니다.
두 클래스는 콜러블을 스케줄링하고 Future 객체를 반환하는 map(), 그리고 리소스를 해제하는 shutdown() 세 가지 메서드를 가진 공통 인터페이스를 공유합니다. 이 클래스는 :term:`context manager`이며, 현재 보류 중인 future가 실행을 완료할 때 자동으로 리소스가 해제되도록 with 문에서 사용할 수 있습니다.
:class:`~concurrent.futures.ThreadPoolExecutor`의 간단한 예로는 파일을 복사하기 위해 네 개의 병렬 스레드를 실행하는 것이 있습니다:
import concurrent.futures, shutil
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as e:
e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
e.submit(shutil.copy, 'src3.txt', 'dest4.txt')
더 보기
- PEP 3148 - 퓨처 – 계산을 비동기적으로 실행하기
Brian Quinlan이 작성한 PEP.
:ref:`Code for Threaded Parallel URL reads<threadpoolexecutor-example>`, 여러 웹 페이지를 병렬로 가져오는 데 스레드를 사용한 예제입니다.
:ref:`Code for computing prime numbers in parallel<processpoolexecutor-example>`, :class:`~concurrent.futures.ProcessPoolExecutor`를 시연하는 예제입니다.
PEP 3147: PYC 저장소 디렉터리¶
Python의 .pyc 파일에 바이트코드를 캐싱하는 방식은 여러 Python 인터프리터가 있는 환경에서 잘 작동하지 않았습니다. 한 인터프리터가 다른 인터프리터에 의해 생성된 캐시 파일을 만나면, 소스를 재컴파일하여 캐시 파일을 덮어쓰고, 따라서 캐싱의 이점을 잃게 됩니다.
“pyc 충돌” 문제는 리눅스 배포판들이 여러 버전의 Python을 포함하는 것이 일반적이 되면서 더욱 두드러지게 되었습니다. 이러한 충돌은 Unladen Swallow와 같은 CPython 대안에서도 발생합니다.
이 문제를 해결하기 위해 Python의 임포트 메커니즘은 각 인터프리터를 위한 고유한 파일명을 사용하도록 확장되었습니다. 이제 Python 3.2와 Python 3.3 및 Unladen Swallow가 모두 “mymodule.pyc”라는 같은 파일을 두고 경쟁하는 대신, 각각 “mymodule.cpython-32.pyc”, “mymodule.cpython-33.pyc”, 그리고 “mymodule.unladen10.pyc”를 찾습니다. 또한 이러한 새 파일들이 소스 디렉터리를 지저분하게 만들지 않도록 pyc 파일들은 이제 패키지 디렉터리 아래에 저장된 “__pycache__” 디렉터리에 모여 있습니다.
파일명과 대상 디렉터리 외에도, 새로운 방식에는 프로그래머에게 보이는 몇 가지 측면이 있습니다:
임포트된 모듈은 이제 실제로 임포트된 파일의 이름을 저장하는
__cached__속성을 갖습니다:>>> import collections >>> collections.__cached__ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
각 인터프리터에 고유한 태그는
imp모듈에서 액세스할 수 있습니다:>>> import imp >>> imp.get_tag() 'cpython-32'
임포트된 파일로부터 소스 파일명을 추론하려고 시도하는 스크립트는 이제 더 스마트해야 합니다. “.pyc” 파일명에서 “c”를 단순히 제거하는 것만으로는 충분하지 않습니다. 대신,
imp모듈의 새 함수들을 사용하십시오:>>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc') 'c:/py32/lib/collections.py' >>> imp.cache_from_source('c:/py32/lib/collections.py') 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
The
py_compileandcompileallmodules have been updated to reflect the new naming convention and target directory. The command-line invocation of compileall has new options:-ifor specifying a list of files and directories to compile and-bwhich causes bytecode files to be written to their legacy location rather than __pycache__.importlib.abc모듈은 바이트 코드 파일을 로딩하기 위한 새로운 추상 기본 클래스 <abstract base class>`로 업데이트되었습니다. 구식이 된 ABC인 :class:!PyLoader`와 :class:`!PyPycLoader`는 사용 중단되었으며 (Python 3.1 호환성을 유지하는 방법에 대한 지침은 문서에 포함되어 있습니다).
더 보기
- PEP 3147 - PYC 저장소 디렉터리
Barry Warsaw가 작성한 PEP입니다.
PEP 3149: ABI 버전 태그가 지정된 .so 파일¶
PYC 저장소 디렉터리는 여러 바이트 코드 캐시 파일을 공존할 수 있도록 합니다. 이 PEP는 공유 객체 파일에 대해 공통 디렉터리를 제공하고 버전별 고유한 이름을 부여하여 유사한 메커니즘을 구현합니다.
공통 디렉터리는 “pyshared”이며, 파일 이름은 파이썬 구현(예: CPython, PyPy, Jython 등), 주요 및 부 버전 번호, 그리고 선택적 빌드 플래그(“d”는 디버그용, “m”은 pymalloc 전용, “u”는 와이드 유니코드용 등)을 식별하여 고유하게 만들어집니다. 임의의 패키지 “foo”의 경우, 배포 패키지가 설치될 때 다음과 같은 파일들이 보일 수 있습니다:
/usr/share/pyshared/foo.cpython-32m.so
/usr/share/pyshared/foo.cpython-33md.so
파이썬 자체에서는 태그가 sysconfig 모듈의 함수들에서 액세스할 수 있습니다:
>>> import sysconfig
>>> sysconfig.get_config_var('SOABI') # 버전 태그 찾기
'cpython-32mu'
>>> sysconfig.get_config_var('EXT_SUFFIX') # 전체 파일명 확장자 찾기
'.cpython-32mu.so'
더 보기
- PEP 3149 - ABI 버전 태그가 지정된 .so 파일
Barry Warsaw가 작성한 PEP입니다.
PEP 3333: Python Web Server Gateway Interface v1.0.1¶
이 정보성 PEP는 WSGI 프로토콜에서 바이트/텍스트 문제가 어떻게 처리되어야 하는지 명확히 설명합니다. 문제는 HTTP 프로토콜 자체가 바이트 기반임에도 불구하고, Python 3의 문자열 처리는 str 타입을 사용하여 가장 편리하게 처리된다는 것입니다.
이 PEP는 요청/응답 헤더 및 메타데이터에 사용되는 네이티브 문자열 과, 요청 및 응답 본문에 사용되는 바이트 문자열 을 구분합니다.
네이티브 문자열 은 항상 str 타입이지만, “U+0000 부터 U+00FF 사이의 코드 포인트로 제한되며 라틴-1 인코딩을 사용하여 바이트로 변환할 수 있습니다. 이 문자열들은 환경 딕셔너리의 키 및 값과 start_response() 함수에서 응답 헤더 및 상태에 사용됩니다. 오직 인코딩 측면에서만 RFC 2616 을 따라야 합니다. 즉, ISO-8859-1 문자이거나 RFC 2047 MIME 인코딩을 사용해야 합니다.
Python 2에서 WSGI 애플리케이션을 포팅하는 개발자를 위해, 다음은 핵심 사항들입니다:
앱이 이미 Python 2에서 헤더에 문자열을 사용했다면, 변경할 필요가 없습니다.
만약 대신 앱이 출력 헤더를 인코딩하거나 입력 헤더를 디코드했다면, 헤더들은 Latin-1로 다시 인코딩해야 합니다. 예를 들어, utf-8로 인코딩된 출력 헤더는 이제
h.encode('utf-8')을 사용하는 대신h.encode('utf-8').decode('latin-1')을 사용하여 바이트를 네이티브 문자열로 변환해야 합니다.앱에서 반환되거나
write()메서드를 사용하여 전송되는 값들은 반드시 바이트 문자열이어야 합니다.start_response()함수와 환경 변수는 네이티브 문자열을 사용해야 합니다. 이 두 가지는 혼합될 수 없습니다.
CGI-to-WSGI 경로를 작성하는 서버 구현자 또는 기타 CGI 스타일 프로토콜 사용자들은, 내부적인 플랫폼이 다른 규칙을 가지고 있을지라도 네이티브 문자열을 사용하여 환경 변수에 접근할 수 있어야 합니다. 이 간극을 메우기 위해 wsgiref 모듈은 :data:`os.environ`의 CGI 변수를 네이티브 문자열로 전사하고 새 딕셔너리를 반환하는 새로운 함수인 :func:`wsgiref.handlers.read_environ`을 가지고 있습니다.
더 보기
- PEP 3333 - Python 웹 서버 게이트웨이 인터페이스 v1.0.1
Phillip Eby가 작성한 PEP입니다.
이외의 언어 변경 사항¶
핵심 파이썬 언어에 일부 작은 변경 사항들이 있습니다.
:func:`format`과 :meth:`str.format`의 문자열 포매팅 기능은 형식 지정자 # 에 대해 새로운 기능을 얻었습니다. 이전에는 바이너리, 8진수 또는 16진수의 정수에 대해서는 각각 ‘0b’, ‘0o’ 또는 ‘0x’으로 접두사를 붙여 출력했습니다. 이제 부동 소수점, 복소수 및 Decimal도 처리할 수 있어, 아무런 자릿수가 따르지 않더라도 출력에 항상 소수점이 있게 합니다.
>>> format(20, '#o') '0o24' >>> format(12.34, '#5.0f') ' 12.'
(Mark Dickinson가 제안하고 Eric Smith가 bpo-7094\에서 구현함.)
기존의
str.format()메서드의 기능을 확장하는 새로운str.format_map()메서드가 있으며, 이는 임의의 mapping 객체를 인수로 받습니다. 이 새 메서드는defaultdict,Shelf,ConfigParser, 또는dbm`과 같은 Python의 다양한 딕셔너리형 객체와 문자열 포매팅을 사용할 수 있게 합니다. 또한 조회 전에 키를 정규화하거나 알 수 없는 키에 대해 :meth:`~object.__missing__메서드를 제공하는 사용자 정의dict서브클래스와도 유용합니다:>>> import shelve >>> d = shelve.open('tmp.shl') >>> 'The {project_name} status is {status} as of {date}'.format_map(d) 'The testing project status is green as of February 15, 2011' >>> class LowerCasedDict(dict): ... def __getitem__(self, key): ... return dict.__getitem__(self, key.lower()) ... >>> lcd = LowerCasedDict(part='widgets', quantity=10) >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd) 'There are 10 widgets in stock' >>> class PlaceholderDict(dict): ... def __missing__(self, key): ... return '<{}>'.format(key) ... >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict()) 'Hello <name>, welcome to <location>'
(Raymond Hettinger가 제안하고 Eric Smith가 bpo-6081\에서 구현함.)
인터프리터를 이제 조용한 옵션
-q로 시작할 수 있어, 대화형 모드에 복사본 및 버전 정보가 표시되는 것을 방지합니다. 이 옵션은sys.flags속성을 사용하여 검사할 수 있습니다:$ python -q >>> sys.flags sys.flags(debug=0, division_warning=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=1)
(Marcin Wojdyr가 bpo-1772833\에서 기여함).
The
hasattr()function works by callinggetattr()and detecting whether an exception is raised. This technique allows it to detect methods created dynamically by__getattr__()or__getattribute__()which would otherwise be absent from the class dictionary. Formerly, hasattr would catch any exception, possibly masking genuine errors. Now, hasattr has been tightened to only catchAttributeErrorand let other exceptions pass through:>>> class A: ... @property ... def f(self): ... return 1 // 0 ... >>> a = A() >>> hasattr(a, 'f') Traceback (most recent call last): ... ZeroDivisionError: integer division or modulo by zero
(Yury Selivanov가 발견하고 Benjamin Peterson이 bpo-9666\에서 수정함.)
float 또는 complex 숫자의
str`은 이제 그 :func:`repr`과 같습니다. 이전에는 :func:`str()형태가 더 짧았지만, 단지 혼란을 야기했을 뿐이며, 기본적으로 가장 짧은 :func:`repr`이 표시되므로 현재는 필요하지 않습니다:>>> import math >>> repr(math.pi) '3.141592653589793' >>> str(math.pi) '3.141592653589793'
(Mark Dickinson이 제안하고 구현함; bpo-9337.)
memoryview객체는 이제release()메서드를 가지며, 또한 컨텍스트 관리 프로토콜을 지원합니다. 이를 통해 원래 객체에서 버퍼를 요청했을 때 획득한 모든 리소스를 적시에 해제할 수 있습니다.>>> with memoryview(b'abcdefgh') as v: ... print(v.tolist()) [97, 98, 99, 100, 101, 102, 103, 104]
(Antoine Pitrou가 bpo-9757\에 추가함.)
이전에 중첩된 블록에서 자유 변수로 등장하는 경우 지역 이름 공간에서 이름을 삭제하는 것은 불법적이었습니다:
def outer(x): def inner(): return x inner() del x
이제 허용됩니다.
except절의 목표가 지워진다는 점을 기억하세요. 따라서 Python 2.6에서는 작동했지만, Python 3.1에서 :exc:`SyntaxError`를 발생시켰던 이 코드가 이제 다시 작동합니다:def f(): def print_error(): print(e) try: something except Exception as e: print_error() # implicit "del e" here
(자세한 내용은 bpo-4617.)
Struct sequence types <struct-sequence-objects>`는 이제 튜플의 서브클래스입니다. 이는 :func:`os.stat,
time.gmtime(), 그리고 :data:`sys.version_info`가 반환하는 C 구조체들이 이제 :term:`named tuple`처럼 작동하며, 인수로 튜플을 예상하는 함수 및 메서드와도 함께 작동함을 의미합니다. 이는 C 구조체를 순수 Python 대응물만큼 유연하게 만드는 큰 진전입니다:>>> import sys >>> isinstance(sys.version_info, tuple) True >>> 'Version %d.%d.%d %s(%d)' % sys.version_info 'Version 3.2.0 final(0)'
(요청자에 의해 제안되었고, :issue:`8413`에서 Benjamin Peterson에 의해 구현되었습니다.)
경고는 더 이상 명령줄에서
-W를 사용하는 것을 대체하여,PYTHONWARNINGS환경 변수를 사용하여 보다 쉽게 제어할 수 있습니다:$ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'
(Barry Warsaw가 제안하고 :issue:`7301`에서 Philip Jenvey에 의해 구현되었습니다.)
새로운 경고 범주인
ResourceWarning`이 추가되었습니다. 이는 리소스 사용 또는 정리와 관련된 잠재적인 문제가 감지될 때 발생합니다. 일반적인 릴리스 빌드에서는 기본적으로 비활성화되어 있지만, :mod:`warnings모듈이나 명령줄을 통해 활성화할 수 있습니다::data:`gc.garbage 목록이 비어 있지 않고, :const:`gc.DEBUG_UNCOLLECTABLE`가 설정되어 있으면 인터프리터 종료 시 :exc:`ResourceWarning`이 발생합니다. 모든 수거할 수 없는 객체가 인쇄됩니다. 이는 프로그래머에게 코드가 객체 최종화 문제를 포함하고 있음을 인식시키기 위함입니다.
:term:`file object`이 명시적으로 닫히지 않은 상태로 파괴될 때도 :exc:`ResourceWarning`이 발생합니다. 이러한 객체의 해제자는 내부 운영 체제 리소스(일반적으로 파일 디스크립터)를 닫도록 보장하지만, 객체를 해제하는 지연은 특히 Windows에서 다양한 문제를 일으킬 수 있습니다. 명령줄에서 경고를 활성화하는 예시는 다음과 같습니다:
$ python -q -Wdefault >>> f = open("foo", "wb") >>> del f __main__:1: ResourceWarning: unclosed file <_io.BufferedWriter name='foo'>
(Antoine Pitrou와 Georg Brandl이 bpo-10093 및 :issue:`477863`에서 추가했습니다.)
rangeobjects now support index and count methods. This is part of an effort to make more objects fully implement thecollections.Sequenceabstract base class. As a result, the language will have a more uniform API. In addition,rangeobjects now support slicing and negative indices, even with values larger thansys.maxsize. This makes range more interoperable with lists:>>> range(0, 100, 2).count(10) 1 >>> range(0, 100, 2).index(10) 5 >>> range(0, 100, 2)[5] 10 >>> range(0, 100, 2)[0:5] range(0, 10, 2)
(Daniel Stutzbach가 :issue:`9213`에서, Alexander Belopolsky가 :issue:`2690`에서, 그리고 Nick Coghlan이 :issue:`10889`에서 기여했습니다.)
Py2.x의 내장 함수인
callable()이 부활했습니다. 이는isinstance(x, collections.Callable)와 같은 표현식에서 abstract base class 를 사용하는 것에 대한 간결하고 가독성 높은 대안을 제공합니다:>>> callable(max) True >>> callable(20) False
(자세한 내용은 bpo-10518.)
Python의 import 메커니즘은 이제 경로 이름에 비 ASCII 문자가 포함된 디렉토리에 설치된 모듈을 로드할 수 있습니다. 이는 사용자 이름에 비 ASCII 문자가 있는 사용자의 홈 디렉터리 관련하여 골치 아팠던 문제를 해결했습니다.
(Victor Stinner가 :issue:`9425`에서 광범위한 작업을 요구했습니다.)
새롭고, 개선되고, 사용 중단된 모듈¶
Python의 표준 라이브러리가 중요한 유지보수 노력과 품질 개선을 거쳤습니다.
Python 3.2에 대한 가장 큰 소식은 email 패키지, mailbox 모듈, 그리고 nntplib 모듈이 이제 Python 3의 바이트/텍스트 모델과 올바르게 작동한다는 것입니다. 혼합 인코딩 메시지를 정확하게 처리하는 것은 처음입니다.
표준 라이브러리 전반에 걸쳐 인코딩 및 텍스트와 바이트 문제에 대해 더욱 세심한 주의가 기울여졌습니다. 특히, 운영 체제와의 상호 작용은 이제 Windows MBCS 인코딩, 로케일 인식 인코딩 또는 UTF-8을 사용하여 비 ASCII 데이터를 교환하는 것이 더 좋아졌습니다:
또 다른 중요한 개선 사항은 SSL 연결 및 보안 인증서에 대한 상당히 향상된 지원이 추가되었다는 점입니다:
In addition, more classes now implement a context manager to support
convenient and reliable resource clean-up using a with statement.
email¶
The usability of the email package in Python 3 has been mostly fixed by
the extensive efforts of R. David Murray. The problem was that emails are
typically read and stored in the form of bytes rather than str
text, and they may contain multiple encodings within a single email. So, the
email package had to be extended to parse and generate email messages in bytes
format.
새 함수
message_from_binary_file(), 그리고 새로운 클래스 :class:`~email.parser.BytesFeedParser`와 :class:`~email.parser.BytesParser`를 사용하여 바이너리 메시지 데이터를 모델 객체로 구문 분석할 수 있습니다.Given bytes input to the model,
get_payload()will by default decode a message body that has a Content-Transfer-Encoding of 8bit using the charset specified in the MIME headers and return the resulting string.Given bytes input to the model,
Generatorwill convert message bodies that have a Content-Transfer-Encoding of 8bit to instead have a 7bit Content-Transfer-Encoding.인코딩되지 않은 비 ASCII 바이트를 포함하는 헤더는 RFC 2047\ 방식으로 unknown-8bit 문자 집합을 사용하여 인코딩된 것으로 간주됩니다.
A new class
BytesGeneratorproduces bytes as output, preserving any unchanged non-ASCII data that was present in the input used to build the model, including message bodies with a Content-Transfer-Encoding of 8bit.smtplibSMTP클래스는 이제sendmail()메서드의 msg 인자에 바이트 문자열을 허용하며, 새로운 메서드인Message()객체를 받아서 옵션으로 from_addr 및 to_addrs 주소를 직접 가져올 수 있습니다.
elementtree¶
The xml.etree.ElementTree package and its xml.etree.cElementTree
counterpart have been updated to version 1.3.
여러 새롭고 유용한 함수와 메서드가 추가되었습니다:
순서화된 조각들로부터 XML 문서를 구축하는
xml.etree.ElementTree.fromstringlist()글로벌 네임스페이스 접두사를 등록하는
xml.etree.ElementTree.register_namespace()모든 하위 리스트를 포함하여 문자열 표현을 제공하는
xml.etree.ElementTree.tostringlist()0개 이상의 요소를 추가하기 위한
xml.etree.ElementTree.Element.extend():meth:`xml.etree.ElementTree.Element.iterfind`는 요소와 하위 요소를 검색합니다.
:meth:`xml.etree.ElementTree.Element.itertext`는 요소 및 그 하위 요소에 대한 텍스트 이터레이터를 생성합니다.
:meth:`xml.etree.ElementTree.TreeBuilder.end`는 현재 요소를 닫습니다.
:meth:`xml.etree.ElementTree.TreeBuilder.doctype`은 doctype 선언을 처리합니다:
두 개의 메서드가 사용 중단되었습니다:
xml.etree.ElementTree.getchildren()은 대신list(elem)을 사용하십시오.xml.etree.ElementTree.getiterator()는 대신Element.iter를 사용하십시오.
업데이트 세부 정보는 Fredrik Lundh의 웹사이트에서 `Introducing ElementTree <https://web.archive.org/web/20200703234532/http://effbot.org/zone/elementtree-13-intro.htm>`_를 참조하십시오.
(Florent Xicluna와 Fredrik Lundh가 기여함, bpo-6472.)
functools¶
The
functoolsmodule includes a new decorator for caching function calls.@functools.lru_cachecan save repeated queries to an external resource whenever the results are expected to be the same.예를 들어, 데이터베이스 쿼리 함수에 캐싱 데코레이터를 추가하면 인기 있는 검색에 대한 데이터베이스 접근을 줄일 수 있습니다:
>>> import functools >>> @functools.lru_cache(maxsize=300) ... def get_phone_number(name): ... c = conn.cursor() ... c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,)) ... return c.fetchone()[0]
>>> for name in user_requests: ... get_phone_number(name) # cached lookup
효과적인 캐시 크기를 선택하는 데 도움을 주기 위해, 래핑된 함수는 캐시 통계 추적용으로 인스트루먼트 됩니다:
>>> get_phone_number.cache_info() CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)
phonelist 테이블이 업데이트되면, 다음 명령어로 오래된 캐시 내용을 지울 수 있습니다:
>>> get_phone_number.cache_clear()
(Raymond Hettinger가 기여하고 Jim Baker, Miki Tebeka 및 Nick Coghlan의 디자인 아이디어를 통합함; recipe 498245 <https://code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/>`_로, recipe 577479 <https://code.activestate.com/recipes/577479-simple-caching-decorator/>`_로, bpo-10586, 및 :issue:`10593`에서 확인하십시오.)
@functools.wraps데코레이터는 이제 원래 호출 가능한 함수를 가리키는__wrapped__속성을 추가합니다. 이를 통해 감싸진 함수를 검사할 수 있습니다. 또한, 정의된 경우 :attr:`~function.__annotations__`도 복사합니다. 그리고 이제는 감싸진 호출 가능 함수의 경우 정의되지 않을 수 있는 :attr:`~function.__doc__`와 같은 누락된 속성을 우아하게 건너<0xEB><0x9C><0x81>니다.위 예제에서는 원래 함수를 복구하여 캐시를 제거할 수 있습니다:
>>> get_phone_number = get_phone_number.__wrapped__ # uncached function
(Nick Coghlan 및 Terrence Cole 작성; bpo-9567, bpo-3445, 및 bpo-8814.)
rich comparison method를 사용하는 클래스를 작성하는 데 도움을 주기 위해, 새로운 데코레이터 :deco:`functools.total_ordering`은 기존의 동등성 및 부등식 메서드를 사용하여 나머지 메서드를 채울 것입니다.
예를 들어, __eq__ 와 __lt__ 를 제공하면
@~functools.total_ordering이 __le__, __gt__ 및 __ge__ 를 채울 수 있게 됩니다:@total_ordering class Student: def __eq__(self, other): return ((self.lastname.lower(), self.firstname.lower()) == (other.lastname.lower(), other.firstname.lower())) def __lt__(self, other): return ((self.lastname.lower(), self.firstname.lower()) < (other.lastname.lower(), other.firstname.lower()))
total_ordering 데코레이터와 함께, 나머지 비교 메서드는 자동으로 채워집니다.
(Raymond Hettinger 작성.)
프로그램을 Python 2에서 마이그레이션하는 데 도움이 되도록,
functools.cmp_to_key()함수는 구식 비교 함수를 최신 :term:`키 함수 <key function>`로 변환합니다:>>> # locale-aware sort order >>> sorted(iterable, key=cmp_to_key(locale.strcoll))
정렬 예제 및 간략한 정렬 튜토리얼은 Sorting HowTo 튜토리얼을 참조하십시오.
(Raymond Hettinger 작성.)
itertools 모듈¶
itertools모듈은 APL의 scan 연산자와 Numpy의 accumulate 함수를 모델링한 새로운accumulate()함수를 가지고 있습니다:>>> from itertools import accumulate >>> list(accumulate([8, 2, 50])) [8, 10, 60]
>>> prob_dist = [0.1, 0.4, 0.2, 0.3] >>> list(accumulate(prob_dist)) # cumulative probability distribution [0.1, 0.5, 0.7, 1.0]
:func:`~itertools.accumulate`을 사용하는 예제는 :ref:`random 모듈의 예제 <random-examples>`를 참조하십시오.
(Raymond Hettinger 작성 및 Mark Dickinson의 디자인 제안 사항 반영.)
컬렉션 모듈(collections)¶
collections.Counter클래스는 이제 인플레이스(in-place) 빼기의 두 가지 형태를 가지고 있습니다. 기존의 -= 연산자는 saturating subtraction <https://en.wikipedia.org/wiki/Saturation_arithmetic>`_에 사용되며, 새로운 :meth:`~collections.Counter.subtract 메서드는 일반적인 뺄셈을 위한 것입니다. 전자는 양수만 갖는 계수기인 `multisets <https://en.wikipedia.org/wiki/Multiset>`_에 적합하며, 후자는 음의 개수를 허용하는 사용 사례에 더 적합합니다:>>> from collections import Counter >>> tally = Counter(dogs=5, cats=3) >>> tally -= Counter(dogs=2, cats=8) # saturating subtraction >>> tally Counter({'dogs': 3})
>>> tally = Counter(dogs=5, cats=3) >>> tally.subtract(dogs=2, cats=8) # regular subtraction >>> tally Counter({'dogs': 3, 'cats': -5})
(Raymond Hettinger 작성.)
collections.OrderedDict클래스는 기존 키를 받아 이를 순서형 시퀀스의 첫 번째 또는 마지막 위치로 이동시키는 새로운 메서드 :meth:`~collections.OrderedDict.move_to_end`를 가지고 있습니다.기본값은 항목을 마지막 위치로 이동하는 것입니다. 이는
od[k] = od.pop(k)와 동일합니다.빠른 move-to-end 작업은 항목의 재순서 지정에 유용합니다. 예를 들어, 순서가 있는 딕셔너리는 가장 오래된 항목부터 가장 최근에 액세스한 항목까지 접근 순서를 추적하는 데 사용될 수 있습니다.
>>> from collections import OrderedDict >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e']) >>> list(d) ['a', 'b', 'X', 'd', 'e'] >>> d.move_to_end('X') >>> list(d) ['a', 'b', 'd', 'e', 'X']
(Raymond Hettinger 작성.)
collections.deque클래스가 두 개의 새로운 메서드reverse`를 추가하여 :class:`list()객체에 대한 대체 가능성을 높였습니다:>>> from collections import deque >>> d = deque('simsalabim') >>> d.count('s') 2 >>> d.reverse() >>> d deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])
(Raymond Hettinger 작성.)
스레딩¶
threading 모듈은 여러 스레드가 모두 공통의 장벽 지점에 도달할 때까지 기다리게 하는 새로운 동기화 클래스인 :class:`~threading.Barrier`를 가지고 있습니다. 장벽은 여러 전제 조건이 있는 작업이 모든 이전 작업이 완료될 때까지 실행되지 않도록 보장하는 데 유용합니다.
장벽은 임의의 수의 스레드와 작동할 수 있습니다. 이것은 두 개의 스레드에만 정의되는 `Rendezvous <https://en.wikipedia.org/wiki/Synchronous_rendezvous>`_을 일반화한 것입니다.
두 단계의 주기적 장벽으로 구현된 Barrier 객체는 루프에서 사용하기에 적합합니다. 별도의 filling 및 draining 단계는 모든 스레드가 방출(drained)되기 전에 어느 스레드도 루프로 돌아가 장벽에 재진입할 수 있도록 보장합니다. 이 장벽은 각 주기 후에 완전히 초기화됩니다.
장벽 사용 예제:
from threading import Barrier, Thread
get_votes(site):
ballots = conduct_election(site)
all_polls_closed.wait() # 모든 투표가 마감될 때까지 카운트하지 않음
totals = summarize(ballots)
publish(site, totals)
all_polls_closed = Barrier(len(sites))
for site in sites:
Thread(target=get_votes, args=(site,)).start()
이 예제에서, 장벽은 모든 투표소(poll)가 마감될 때까지 투표를 집계할 수 없다는 규칙을 강제합니다. 장벽을 사용한 솔루션이 :meth:`threading.Thread.join`을 사용한 솔루션과 유사하지만, 스레드가 살아남아 (투표집계를 계속하여) 장벽 지점을 넘어선 후 작업하는 방식에 유의하세요.
선행 작업 중 하나라도 멈추거나 지연될 수 있는 경우, 선택적 timeout 매개변수와 함께 장벽을 생성할 수 있습니다. 이때 시간 초과 기간이 모든 선행 작업이 장벽 지점에 도달하기 전에 만료되면, 기다리던 모든 스레드가 해제되고 BrokenBarrierError 예외가 발생합니다:
def get_votes(site):
ballots = conduct_election(site)
try:
all_polls_closed.wait(timeout=midnight - time.now())
except BrokenBarrierError:
lockbox = seal_ballots(ballots)
queue.put(lockbox)
else:
totals = summarize(ballots)
publish(site, totals)
이 예제에서, 장벽은 더 강력한 규칙을 강제합니다. 만약 일부 선거장이 자정까지 완료되지 않으면, 장벽에 시간 초과가 발생하고 투표용지가 밀봉되어 나중에 처리하기 위해 대기열에 저장됩니다.
장벽을 병렬 컴퓨팅에서 어떻게 사용할 수 있는지에 대한 더 많은 예시는 Barrier Synchronization Patterns <https://osl.cs.illinois.edu/media/papers/karmani-2009-barrier_synchronization_pattern.pdf> 를 참조하세요. 또한, 여기에는 The Little Book of Semaphores <https://greenteapress.com/semaphores/LittleBookOfSemaphores.pdf> 의 섹션 3.6 에 장벽에 대한 간단하지만 철저한 설명이 있습니다.
(Kristján Valur Jónsson가 작성하고 Jeffrey Yasskin이 :issue:`8777`에서 API 검토를 진행했습니다.)
datetime 및 time¶
datetime모듈에는 고정된 UTC 오프셋과 시간대 이름을 반환하여tzinfo인터페이스를 구현하는 새로운 타입인 :class:`~datetime.timezone`이 있습니다. 이로써 시간대 인식 datetime 객체를 생성하기가 더욱 쉬워집니다:>>> import datetime as dt >>> dt.datetime.now(dt.timezone.utc) datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc) >>> dt.datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z") datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
또한,
timedelta객체는 이제float및float`와 :class:`int객체로 곱하거나 나눌 수 있습니다. 그리고timedelta객체들은 서로 나누어질 수도 있게 되었습니다.datetime.date.strftime()메서드는 더 이상 1900년 이후 연도에만 제한되지 않습니다. 이제 지원되는 연도 범위는 1000년부터 9999년까지 포함됩니다.time 튜플에서 두 자리 연도가 사용될 때마다, 해석은
time.accept2dyear`에 의해 지배되어 왔습니다. 기본값은 `True`이며, 이는 두 자릿수 연도의 경우 POSIX 규칙이 적용되는 ``%y`strptime 포맷에 따라 세기가 추측된다는 것을 의미합니다.Py3.2부터,세기 추측 휴리스틱을 사용하면
DeprecationWarning이 발생하게 됩니다. 대신,time.accept2dyear를False로 설정하여 추측 없이 큰 날짜 범위를 사용할 것을 권장합니다:>>> import time, warnings >>> warnings.resetwarnings() # 기본 경고 필터 제거에 사용 >>> time.accept2dyear = True # 11이 11년인지 2011년인지 추측하기 위해 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0)) Warning (from warnings module): ... DeprecationWarning: Century info guessed for a 2-digit year. 'Fri Jan 1 12:34:56 2011' >>> time.accept2dyear = False # 허용 가능한 날짜의 전체 범위를 사용하기 위해 >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0)) 'Fri Jan 1 12:34:56 11'
여러 함수가 이제 상당히 확장된 날짜 범위를 갖게 되었습니다.
time.accept2dyear`가 false인 경우, :func:`time.asctime함수는 C int에 들어가는 모든 연도를 허용하며,time.mktime()및time.strftime()함수는 해당 운영 체제 함수가 지원하는 전체 범위를 허용합니다.
(Alexander Belopolsky와 Victor Stinner가 bpo-1289118, bpo-5094, bpo-6641, bpo-2706, bpo-1777412, bpo-8013, 및 :issue:`10827`에서 기여했습니다.)
math 모듈¶
math 모듈은 C99 표준에서 영감을 받은 여섯 가지 새 함수로 업데이트되었습니다.
isfinite() 함수는 특수 값을 감지하는 믿을 수 있고 빠른 방법을 제공합니다. 정규 숫자에 대해서는 True 를, NaN 또는 Infinity 에 대해서는 False 를 반환합니다:
>>> from math import isfinite
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]
expm1() 함수는 x 가 작은 값일 때 e**x-1 을 계산하며, 이 과정에서 일반적으로 동등한 값을 뺀 것과 관련된 정밀도 손실이 발생하지 않습니다:
>>> from math import expm1
>>> expm1(0.013671875) # more accurate way to compute e**x-1 for a small x
0.013765762467652909
erf() 함수는 확률 적분 또는 가우스 에러 함수 <https://en.wikipedia.org/wiki/Error_function> 을 계산하는 데 사용될 수 있습니다. 여측 에러 함수인 erfc() 는 1 - erf(x) 입니다:
>>> from math import erf, erfc, sqrt
>>> erf(1.0/sqrt(2.0)) # 표준 편차 1 범위 내의 정규 분포 비율
0.682689492137086
>>> erfc(1.0/sqrt(2.0)) # 표준 편차 1 범위 외의 정규 분포 비율
0.31731050786291404
>>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
1.0
gamma() 함수는 팩토리얼 함수의 연속 확장입니다. 자세한 내용은 https://en.wikipedia.org/wiki/Gamma_function을 참조하십시오. 이 함수는 팩토리얼과 관련이 있어 x 가 작은 값일 때도 크게 증가하므로, 감마 함수의 자연 로그를 계산하기 위한 lgamma() 함수도 있습니다:
>>> from math import gamma, lgamma
>>> gamma(7.0) # six factorial
720.0
>>> lgamma(801.0) # log(800 factorial)
4551.950730698041
(Mark Dickinson 기여.)
abc¶
abc 모듈은 이제 @~abc.abstractclassmethod 및 :deco:`~abc.abstractstaticmethod`를 지원합니다:
These tools make it possible to define an abstract base class that
requires a particular @classmethod or @staticmethod to be
implemented:
class Temperature(metaclass=abc.ABCMeta):
@abc.abstractclassmethod
def from_fahrenheit(cls, t):
...
@abc.abstractclassmethod
def from_celsius(cls, t):
...
(Daniel Urban이 제출한 패치; bpo-5867.)
io 모듈¶
:class:`io.BytesIO`는 `:func:`memoryview`와 유사한 기능을 제공하는 새로운 메서드인 :meth:`~io.BytesIO.getbuffer`를 가지고 있습니다. 복사본을 만들지 않고 데이터의 편집 가능한 뷰를 생성합니다. 버퍼의 임의 접근과 슬라이스 표기법 지원은 제자리 편집에 적합합니다:
>>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11
>>> def change_location(buffer, record_number, location):
... start = record_number * REC_LEN + LOC_START
... buffer[start: start+LOC_LEN] = location
>>> import io
>>> byte_stream = io.BytesIO(
... b'G3805 storeroom Main chassis '
... b'X7899 shipping Reserve cog '
... b'L6988 receiving Primary sprocket'
... )
>>> buffer = byte_stream.getbuffer()
>>> change_location(buffer, 1, b'warehouse ')
>>> change_location(buffer, 0, b'showroom ')
>>> print(byte_stream.getvalue())
b'G3805 showroom Main chassis '
b'X7899 warehouse Reserve cog '
b'L6988 receiving Primary sprocket'
(Antoine Pitrou 기여; bpo-5506.)
reprlib¶
사용자 지정 컨테이너에 대해 __repr__() 메서드를 작성할 때, 멤버가 자신(컨테이너 자체)을 가리키는 경우를 처리하는 것을 잊기 쉽습니다. list 및 :class:`set`과 같은 파이썬 내장 객체들은 재귀적 표현 문자열의 부분에 “…”을 표시하여 자기 참조를 처리합니다:
To help write such __repr__() methods, the reprlib module has a new
decorator, @~reprlib.recursive_repr, for detecting recursive calls to
__repr__() and substituting a placeholder string instead:
>>> class MyList(list):
... @recursive_repr()
... def __repr__(self):
... return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>
logging 모듈¶
위에 설명된 딕셔너리 기반 구성 외에도, logging 패키지는 다른 많은 개선 사항을 가지고 있습니다:
로깅 문서에는 기본 튜토리얼, 고급 튜토리얼 및 로깅 레시피의 :ref:`레시피 북 <logging-cookbook>`이 추가되었습니다. 이 문서는 로깅에 대해 학습하는 가장 빠른 방법입니다:
logging.basicConfig() 설정 함수는 세 가지 다른 유형의 문자열 서식을 지원하기 위해 style 인수를 얻었습니다. 기본값은 전통적인 %-포맷팅의 “%”이며, 새로운 str.format() 스타일을 위한 “{“로 설정하거나, :class:`string.Template`에서 제공하는 셸 스타일 포맷팅을 위한 “$”로 설정할 수 있습니다. 다음 세 가지 구성은 동등합니다:
>>> from logging import basicConfig
>>> basicConfig(style='%', format="%(name)s -> %(levelname)s: %(message)s")
>>> basicConfig(style='{', format="{name} -> {levelname} {message}")
>>> basicConfig(style='$', format="$name -> $levelname: $message")
로그 이벤트가 발생하기 전에 구성이 설정되지 않은 경우, 이제 WARNING 수준 이상의 이벤트를 위해 :class:`~logging.StreamHandler`를 `:data:`sys.stderr`로 지시하는 기본 구성이 있습니다. 이전에는 구성을 설정하기 전에 발생하는 이벤트는 :data:`logging.raiseExceptions`의 값에 따라 예외를 발생시키거나 이벤트를 조용히 무시했습니다. 새로운 기본 핸들러는 :data:`logging.lastResort`에 저장됩니다:
필터 사용이 간소화되었습니다. Filter 객체를 생성하는 대신, 술어는 True 또는 False 를 반환하는 모든 Python 호출 가능 객체일 수 있습니다:
유연성을 더하고 구성을 단순화하는 여러 다른 개선 사항이 있었습니다. Python 3.2의 전체 변경 목록은 모듈 문서를 참조하십시오:
csv¶
The csv module now supports a new dialect, unix_dialect,
which applies quoting for all fields and a traditional Unix style with '\n' as
the line terminator. The registered dialect name is unix.
:class:`csv.DictWriter`에는 필드 이름을 기록하는 초기 행을 출력하기 위한 새로운 메서드인 :meth:`~csv.DictWriter.writeheader`가 추가되었습니다.
>>> import csv, sys
>>> w = csv.DictWriter(sys.stdout, ['name', 'dept'], dialect='unix')
>>> w.writeheader()
"name","dept"
>>> w.writerows([
... {'name': 'tom', 'dept': 'accounting'},
... {'name': 'susan', 'dept': 'Salesl'}])
"tom","accounting"
"susan","sales"
(Jay Talbot가 :issue:`5975`에서 제안했고, Ed Abraham이 :issue:`1537721`에서 새로운 메서드를 제안했습니다.)
contextlib¶
There is a new and slightly mind-blowing tool
ContextDecorator that is helpful for creating a
context manager that does double duty as a function decorator.
편의를 위해 이 새로운 기능은 :deco:`~contextlib.contextmanager`에 의해 사용되므로, 두 역할 모두를 지원하기 위한 추가적인 노력이 필요하지 않습니다.
기본 아이디어는 컨텍스트 관리자와 함수 데코레이터 모두 전(前)-액션 및 후(後)-액션 래퍼에 사용될 수 있다는 것입니다. 컨텍스트 관리자는 with 문을 사용하여 일련의 구문을 감싸며, 함수 데코레이터는 함수로 둘러싸인 일련의 구문을 감쌉니다. 따라서 때로는 두 역할 중 어느 쪽에서든 사용될 수 있는 전(前)-액션 또는 후(後)-액션 래퍼를 작성할 필요가 생길 수도 있습니다.
예를 들어, 진입 시간과 탈출 시간을 추적하는 로거로 함수나 구문 그룹을 감싸는 것이 때때로 유용합니다. 작업에 대해 함수 데코레이터와 컨텍스트 관리자를 모두 작성하는 대신, :deco:`~contextlib.contextmanager`가 단일 정의에서 두 가지 기능을 제공합니다:
from contextlib import contextmanager
import logging
logging.basicConfig(level=logging.INFO)
@contextmanager
def track_entry_and_exit(name):
logging.info('Entering: %s', name)
yield
logging.info('Exiting: %s', name)
이전에는 이것을 오직 컨텍스트 관리자로만 사용할 수 있었습니다:
with track_entry_and_exit('위젯 로더'):
print('시간 소모 활동이 여기에 들어갑니다')
load_widget()
이제 데코레이터로도 사용할 수 있습니다:
@track_entry_and_exit('위젯 로더')
def activity():
print('시간 소모 활동이 여기에 들어갑니다')
load_widget()
두 역할을 동시에 수행하려 하면 몇 가지 제한이 따릅니다. 컨텍스트 관리자는 일반적으로 with 문에서 사용 가능한 인수를 반환하는 유연성이 있지만, 함수 데코레이터에는 그러한 병행되는 것이 없습니다.
위 예시에서 track_entry_and_exit 컨텍스트 관리자가 캡슐화된 구문의 본문에서 사용할 로깅 인스턴스를 반환하는 깔끔한 방법이 없습니다.
(Michael Foord가 :issue:`9110`에 기여했습니다.)
decimal 및 fractions¶
Mark Dickinson은 서로 다른 숫자 데이터형이 실제 값이 같을 때 항상 같은 해시값을 갖도록 보장하는 우아하고 효율적인 방식을 만들었습니다 (bpo-8188):
assert hash(Fraction(3, 2)) == hash(1.5) == \
hash(Decimal("1.5")) == hash(complex(1.5, 0))
해싱 세부 정보 중 일부는 새로운 속성인 sys.hash_info 를 통해 노출되는데, 이는 해시값의 비트 폭, 소수 모듈로, infinity 와 nan 에 대한 해시값, 그리고 숫자의 허수 부분에 사용되는 승수를 설명합니다:
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)
다양한 숫자형의 상호 운용성을 제한했던 초기의 결정이 완화되었습니다. Decimal('1.1') + float('1.1') 과 같이 산술 표현식에서 암시적인 혼합을 하는 것은 여전히 지원되지 않습니다 (그리고 바람직하지도 않습니다). 왜냐하면 후자는 바이너리 부동 소수점 생성 과정에서 정보를 잃기 때문입니다. 그러나 기존의 부동 소수점 값은 디시멀 또는 유리 표기법으로 손실 없이 변환될 수 있으므로, 이를 생성자에 추가하고 혼합형 비교를 지원하는 것이 의미가 있습니다.
decimal.Decimal생성자는 이제float객체를 직접 받으므로, 더 이상from_float()메서드를 사용할 필요가 없습니다 (bpo-8257).혼합형 비교가 완전히 지원되므로,
Decimal객체를float및fractions.Fraction`과 직접 비교할 수 있습니다 (:issue:`2531및 bpo-8188).
fractions.Fraction`에도 유사한 변경 사항이 적용되어, :meth:`~fractions.Fraction.from_float`와 :meth:`~fractions.Fraction.from_decimal 메서드가 더 이상 필요하지 않습니다 (bpo-8294):
>>> from decimal import Decimal
>>> from fractions import Fraction
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
decimal 모듈에는 Context.clamp 어트리뷰트가 이제 공개되었습니다. 이는 IEEE 754에서 지정한 십진 교환 형식에 해당하는 컨텍스트를 생성하는 데 유용합니다 (참고 bpo-8540).
(Mark Dickinson 및 Raymond Hettinger 기여)
ftp¶
ftplib.FTP 클래스는 이제 컨텍스트 관리 프로토콜을 지원하여, socket.error 예외를 무조건적으로 처리하고 작업 완료 시 FTP 연결을 닫습니다:
>>> from ftplib import FTP
>>> with FTP("ftp1.at.proftpd.org") as ftp:
ftp.login()
ftp.dir()
'230 Anonymous login ok, restrictions apply.'
dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
mmap.mmap 및 :func:`fileinput.input`과 같은 다른 파일류 객체들도 자동 종료 컨텍스트 관리자를 갖게 되었습니다:
with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
for line in f:
process(line)
(Tarek Ziadé 및 Giampaolo Rodolà 기여 in bpo-4972, 그리고 Georg Brandl 기여 in bpo-8046 및 bpo-1286.)
FTP_TLS 클래스는 이제 context 매개 변수를 받으며, 이는 SSL 구성 옵션, 인증서 및 개인 키를 단일 (잠재적으로 오래 지속되는) 구조로 묶을 수 있는 ssl.SSLContext 객체입니다.
(Giampaolo Rodolà 기여; bpo-8806.)
popen¶
os.popen() 및 subprocess.Popen() 함수는 이제 파일 디스크립터를 자동 종료하기 위해 with 문을 지원합니다.
선택¶
select 모듈은 이제 새 상수 어트리뷰트인 PIPE_BUF 를 노출합니다. 이는 select.select() 가 파이프가 쓰기 준비가 되었다고 알려줄 때 블록되지 않는 최소 바이트 수를 제공합니다.
>>> import select
>>> select.PIPE_BUF
512
(유닉스 시스템에서 사용 가능. :issue:`9862`의 Sébastien Sablé 패치)
gzip 및 zipfile¶
gzip.GzipFile now implements the io.BufferedIOBase
abstract base class (except for truncate()). It also has a
peek() method and supports unseekable as well as
zero-padded file objects.
gzip 모듈은 또한 메모리 내 압축 및 압축 해제를 용이하게 하는 compress() 및 decompress() 함수를 갖게 되었습니다. 텍스트는 압축 및 압축 해제 전에 반드시 :class:`bytes`로 인코딩해야 한다는 점에 유의하십시오:
>>> import gzip
>>> s = 'Three shall be the number thou shalt count, '
>>> s += 'and the number of the counting shall be three'
>>> b = s.encode() # convert to utf-8
>>> len(b)
89
>>> c = gzip.compress(b)
>>> len(c)
77
>>> gzip.decompress(c).decode()[:42] # decompress and convert to text
'Three shall be the number thou shalt count'
(Anand B. Pillai 기여 in bpo-3488; 그리고 Antoine Pitrou, Nir Aides 및 Brian Curtin 기여 in bpo-9962, bpo-1675951, bpo-7471 및 bpo-2846.)
또한, zipfile.ZipExtFile 클래스는 아카이브 내부에 저장된 파일을 나타내도록 내부적으로 수정되었습니다. 이 새 구현은 훨씬 빠르며 속도 향상을 위해 io.BufferedReader 객체로 래핑할 수 있습니다. 또한 read 와 readline 의 교차 호출이 잘못된 결과를 반환하는 문제도 해결했습니다.
(Nir Aides 기여 in bpo-7610.)
타르파일¶
TarFile 클래스는 이제 컨텍스트 관리자로 사용될 수 있습니다. 게다가, 이의 add() 메서드에는 아카이브에 추가할 파일을 제어하고 파일 메타데이터를 편집할 수 있게 하는 새 옵션인 filter 가 있습니다.
The new filter option replaces the older, less flexible exclude parameter
which is now deprecated. If specified, the optional filter parameter needs to
be a keyword argument. The user-supplied filter function accepts a
TarInfo object and returns an updated
TarInfo object, or if it wants the file to be excluded, the
function can return None:
>>> import tarfile, glob
>>> def myfilter(tarinfo):
... if tarinfo.isfile(): # 실제 파일만 저장합니다
... tarinfo.uname = 'monty' # 사용자 이름 수정
... return tarinfo
>>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
... for filename in glob.glob('*.txt'):
... tf.add(filename, filter=myfilter)
... tf.list()
-rw-r--r-- monty/501 902 2011-01-26 17:59:11 annotations.txt
-rw-r--r-- monty/501 123 2011-01-26 17:59:11 general_questions.txt
-rw-r--r-- monty/501 3514 2011-01-26 17:59:11 prion.txt
-rw-r--r-- monty/501 124 2011-01-26 17:59:11 py_todo.txt
-rw-r--r-- monty/501 1399 2011-01-26 17:59:11 semaphore_notes.txt
(Tarek Ziadé가 제안하고 Lars Gustäbel이 :issue:`6856`에서 구현했습니다.)
hashlib¶
hashlib 모듈은 모든 구현체에 존재가 보장되는 해싱 알고리즘과 현재 구현에서 사용 가능한 해싱 알고리즘 목록을 나열하는 두 가지 새로운 상수 속성을 가집니다:
>>> import hashlib
>>> hashlib.algorithms_guaranteed
{'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}
>>> hashlib.algorithms_available
{'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',
'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',
'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',
'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}
(Carl Chenet가 :issue:`7418`에서 제안했습니다.)
ast¶
ast 모듈은 Python 리터럴 구문을 사용하여 표현식 문자열을 안전하게 평가하기 위한 훌륭한 범용 도구를 제공합니다. ast.literal_eval() 함수는 쉽게 남용될 수 있는 내장 함수 eval() 에 대한 보안 대체재 역할을 합니다. Python 3.2에서는 지원되는 타입 목록에 bytes 와 set 리터럴을 추가합니다: 문자열, 바이트, 숫자, 튜플, 리스트, 딕셔너리, 세트, 부울 및 None 입니다.
>>> from ast import literal_eval
>>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
>>> literal_eval(request)
{'args': (2, 0.5), 'req': 3, 'func': 'pow'}
>>> request = "os.system('do something harmful')"
>>> literal_eval(request)
Traceback (most recent call last):
...
ValueError: malformed node or string: <_ast.Call object at 0x101739a10>
(Benjamin Peterson과 Georg Brandl이 구현했습니다.)
os¶
운영 체제마다 파일 이름과 환경 변수에 다양한 인코딩을 사용합니다. os 모듈은 파일 이름을 인코딩하고 디코딩하기 위해 두 개의 새로운 함수, :func:`~os.fsencode`와 :func:`~os.fsdecode`를 제공합니다:
>>> import os
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'
일부 운영 체제는 환경 변수에서 인코딩된 바이트에 직접 액세스할 수 있도록 합니다. 그러한 경우, os.supports_bytes_environ 상수는 True가 됩니다.
인코딩된 환경 변수에 직접 액세스하려면(사용 가능하다면), 새로운 os.getenvb() 함수를 사용하거나, :data:`os.environ`의 바이트 버전인 :data:`os.environb`를 사용하십시오.
(Victor Stinner가 기여했습니다.)
shutil 모듈¶
shutil.copytree() 함수는 두 가지 새로운 옵션을 가집니다:
ignore_dangling_symlinks:
symlinks=False일 때, 즉 함수가 심볼릭 링크 자체를 복사하는 것이 아니라 심볼릭 링크가 가리키는 파일을 복사하도록 합니다. 이 옵션은 파일이 존재하지 않을 경우 발생하는 오류를 침묵시킵니다.copy_function: 파일을 복사하는 데 사용될 콜러블입니다. 기본적으로 :func:`shutil.copy2`가 사용됩니다.
(Tarek Ziadé가 기여했습니다.)
또한, shutil 모듈은 이제 zip 파일, 압축되지 않은 tar 파일, gzip으로 압축된 tar 파일 및 bzip2로 압축된 tar 파일에 대한 :ref:`archiving operations <archiving-operations>`를 지원합니다. 그리고 추가 아카이빙 파일 형식(예: xz으로 압축된 tar 파일 또는 사용자 정의 형식)을 등록하는 함수들도 있습니다.
주요 함수는 :func:`~shutil.make_archive`와 :func:`~shutil.unpack_archive`입니다. 기본적으로 두 함수 모두 현재 디렉터리( :func:`os.chdir`로 설정 가능) 및 모든 하위 디렉터리에서 작동합니다. 아카이브 파일 이름은 전체 경로명으로 지정해야 합니다. 아카이빙 단계는 비파괴적입니다(원본 파일은 변경되지 않습니다).
>>> import shutil, pprint
>>> os.chdir('mydata') # 소스 디렉터리로 변경합니다
>>> f = shutil.make_archive('/var/backup/mydata',
... 'zip') # 현재 디렉터리를 아카이브합니다
>>> f # 아카이브 이름을 표시합니다
'/Users/tarek/myarchive.tar'
>>> os.chdir('tmp') # 압축 해제할 디렉터리로 변경합니다
>>> shutil.unpack_archive('/var/backup/mydata.zip') # 데이터를 복원합니다
>>> pprint.pprint(shutil.get_archive_formats()) # 알려진 형식을 표시합니다
[('bztar', "bzip2'ed tar-file"),
('gztar', "gzip'ed tar-file"),
('tar', 'uncompressed tar file'),
('zip', 'ZIP file')]
>>> shutil.register_archive_format( # 새로운 아카이브 형식을 등록합니다
... name='xz',
... function=xz.compress, # 콜러블 아카이빙 함수
... extra_args=[('level', 8)], # 함수에 대한 인자
... description='xz 압축'
... )
(Tarek Ziadé가 기여했습니다.)
sqlite3 모듈¶
sqlite3 모듈이 pysqlite 버전 2.6.0으로 업데이트되었습니다. 이 모듈에는 두 가지 새로운 기능이 추가되었습니다.
sqlite3.Connection.in_transit속성은 커밋되지 않은 변경 사항에 대해 활성 트랜잭션이 존재하는 경우 True입니다.sqlite3.Connection.enable_load_extension()및sqlite3.Connection.load_extension()메서드를 사용하면 “.so” 파일에서 SQLite 확장을 로드할 수 있습니다. 잘 알려진 확장 중 하나는 SQLite와 함께 배포되는 fulltext-search 확장입니다.
(R. David Murray와 Shashwat Anand가 기여했습니다. bpo-8845.)
HTML¶
A new html module was introduced with only a single function,
escape(), which is used for escaping reserved characters from HTML
markup:
>>> import html
>>> html.escape('x > 2 && x < 7')
'x > 2 && x < 7'
소켓¶
socket 모듈에는 두 가지 새로운 개선 사항이 추가되었습니다.
ssl¶
ssl 모듈은 안전한 (암호화되고 인증된) 인터넷 연결에 대한 일반적인 요구 사항을 충족하기 위해 여러 기능을 추가했습니다:
새로운 클래스인
wrap_socket메서드를 포함하여 SSL 컨텍스트로부터 SSL 소켓을 생성합니다.새 함수인
ssl.match_hostname`은 더 높은 수준의 프로토콜에 대한 서버 신원 검증을 지원하며, 이는 HTTPS (rfc:`2818())의 규칙을 구현하여 다른 프로토콜에도 적합합니다.ssl.wrap_socket()생성자 함수는 이제 ciphers 인수를 받습니다. ciphers 문자열은 `OpenSSL documentation <https://docs.openssl.org/1.0.2/man1/ciphers/#cipher-list-format>`에 설명된 형식으로 허용되는 암호화 알고리즘 목록입니다.최신 버전의 OpenSSL과 연결된 경우,
ssl모듈은 이제 TLS 프로토콜의 서버 이름 표시(Server Name Indication) 확장 기능을 지원하여 단일 IP 포트를 사용하여 서로 다른 인증서를 이용한 여러 “가상 호스트”를 허용합니다. 이 확장은 클라이언트 모드에서만 지원되며, :meth:`ssl.SSLContext.wrap_socket`에 server_hostname 인수를 전달함으로써 활성화됩니다.ssl모듈에는 보안되지 않고 구식인 SSLv2 프로토콜을 비활성화하는 :data:`~ssl.OP_NO_SSLv2`와 같은 여러 옵션이 추가되었습니다.확장은 이제 모든 OpenSSL 사이퍼 및 다이제스트 알고리즘을 로드합니다. 일부 SSL 인증서를 확인할 수 없는 경우 “알 수 없는 알고리즘” 오류로 보고됩니다.
사용 중인 OpenSSL 버전 정보는 이제 모듈 속성
ssl.OPENSSL_VERSION(문자열),ssl.OPENSSL_VERSION_INFO(5-튜플), 및ssl.OPENSSL_VERSION_NUMBER(정수)를 사용하여 액세스할 수 있습니다.
(Antoine Pitrou 기여; bpo-8850, bpo-1589, bpo-8322, bpo-5639, bpo-4870, bpo-8484, 및 bpo-8321.)
nntp¶
nntplib 모듈은 더 나은 바이트 및 텍스트 의미론과 보다 실용적인 API를 갖춘 개편된 구현을 가집니다. 이러한 개선 사항은 자체적으로 부분적으로 작동하지 않았던 Python 3.1 버전의 nntplib 버전과의 호환성을 깨뜨립니다.
내재적 연결( nntplib.NNTP_SSL 사용)과 명시적 연결(nntplib.NNTP.starttls() 사용) 모두를 통한 보안 연결 지원이 추가되었습니다.
인증서¶
http.client.HTTPSConnection, urllib.request.HTTPSHandler 및 :func:`urllib.request.urlopen`은 이제 서버 인증서를 일련의 인증 기관과 비교할 수 있도록 선택적 인수를 받습니다. 이는 HTTPS의 공개적인 사용에서 권장되는 방식입니다.
(Antoine Pitrou 추가; bpo-9003.)
imaplib¶
새로운 imaplib.IMAP4.starttls 메서드를 통해 표준 IMAP4 연결에 대한 명시적 TLS 지원이 추가되었습니다.
(Lorenzo M. Catucci 및 Antoine Pitrou 기여; bpo-4471.)
http.client¶
http.client 모듈에 몇 가지 작은 API 개선 사항이 있었습니다. 구식 HTTP 0.9 단순 응답은 더 이상 지원되지 않으며, 모든 클래스에서 strict 매개 변수가 사용 중단되었습니다.
HTTPConnection 및 HTTPSConnection 클래스는 이제 HTTP 연결이 어디에서 발생하는지를 나타내는 (호스트, 포트) 튜플을 위한 source_address 매개 변수를 가집니다.
:class:`~http.client.HTTPSConnection`에 인증서 확인 및 HTTPS 가상 호스트 지원이 추가되었습니다.
request() 메서드는 연결 객체에서 선택적 body 인수를 허용하여 요청의 내용을 제공하는 file object`를 사용할 수 있게 했습니다. 편리하게도, 이 *body* 인수는 명시적인 ``Content-Length` 헤더만 포함되어 있다면 이제 iterable 객체도 받을 수 있습니다. 이러한 확장된 인터페이스는 이전보다 훨씬 유연합니다.
프록시 서버를 통해 HTTPS 연결을 설정하려면, HTTP Connect 터널링을 위한 호스트와 포트를 설정하는 새로운 set_tunnel() 메서드가 있습니다.
http.server`의 동작을 일치시키기 위해, HTTP 클라이언트 라이브러리가 이제 ISO-8859-1 (Latin-1) 인코딩으로 헤더를 인코딩합니다. 이미 들어오는 헤더에 대해서는 그렇게 처리하고 있었으므로, 이제 입/출력 트래픽 모두에 대해 동작이 일관됩니다. (Armin Ronacher의 :issue:`10980 작업 참고.)
unittest`¶
The unittest 모듈은 패키지에 대한 테스트 검색을 지원하는 여러 개선 사항, 대화형 프롬프트에서의 쉬운 실험, 새로운 테스트 사례 메서드, 테스트 실패에 대한 향상된 진단 메시지 및 더 나은 메서드 이름을 제공합니다.
명령줄 호출
python -m unittest는 이제 특정 테스트를 실행하기 위해 모듈 이름 대신 파일 경로를 허용할 수 있습니다 (bpo-10620). 새로운 테스트 검색을 통해 패키지 내의 모든 테스트를 찾을 수 있으며, 최상위 디렉토리에서 가져올 수 있는 모든 테스트를 위치시킵니다. 최상위 디렉토리는-t옵션으로 지정하고, 파일 일치 패턴은-p로, 테스트 검색을 시작할 디렉토리는-s로 지정할 수 있습니다.$ python -m unittest discover -s my_proj_dir -p _test.py
(Michael Foord 기여.)
unittest.TestCase클래스가 인자 없이도 인스턴스화될 수 있으므로, 대화형 프롬프트에서 실험하기가 더욱 용이합니다.>>> from unittest import TestCase >>> TestCase().assertEqual(pow(2, 3), 8)
(Michael Foord 기여.)
unittest모듈에는 주어진 경고 유형이 테스트하려는 코드에 의해 트리거되는지 확인하는 두 가지 새 메서드, :meth:`~unittest.TestCase.assertWarns`와 :meth:`~unittest.TestCase.assertWarnsRegex`가 있습니다:with self.assertWarns(DeprecationWarning): legacy_function('XYZ')
(Antoine Pitrou 기여, bpo-9754.)
또 다른 새 메서드인 :meth:`~unittest.TestCase.assertCountEqual`은 두 이터러블의 요소 개수가 같은지(순서에 관계없이 동일한 요소가 동일한 수의 개수로 존재하는지) 결정하기 위해 비교하는 데 사용됩니다:
def test_anagram(self): self.assertCountEqual('algorithm', 'logarithm')
(Raymond Hettinger 작성.)
unittest 모듈의 주요 기능 중 하나는 테스트가 실패했을 때 의미 있는 진단을 제공하려는 노력입니다. 가능하면 실패와 함께 출력의 diff도 기록합니다. 이는 실패한 테스트 실행 로그 파일을 분석하는 데 특히 유용합니다. 하지만 diff 파일이 가끔 방대할 수 있으므로, 표시되는 diff의 최대 길이를 설정하는 새로운
maxDiff속성이 있습니다.또한 모듈 내 메서드 이름에 여러 가지 정리 작업이 있었습니다.
예를 들어,
match`를 사용하지 않기 때문에 이름이 잘못 지정되었던 :meth:()!assertRegexpMatches`의 새 이름입니다. 정규 표현식을 사용하는 다른 메서드들은 이제 “Regexp” 대신 짧은 형식인 “Regex”로 이름을 지정하는 것이 선호됩니다. 이는 다른 unittest 구현에서 사용되는 이름과 일치하며, Python의 오래된re모듈 이름과도 일치하고, 명확한 카멜 케이스를 갖추고 있습니다.(Raymond Hettinger 기여 및 Ezio Melotti 구현.)
일관성을 높이기 위해, 오랫동안 사용되어 온 일부 메서드 별칭이 선호하는 이름으로 폐지되고 있습니다:
기존 이름
선호되는 이름
assert_()assertEquals()assertNotEquals()assertAlmostEquals()assertNotAlmostEquals()마찬가지로, Python 3.1에서 폐지된
TestCase.fail*메서드들은 Python 3.3에서 제거될 것으로 예상됩니다.(Ezio Melotti 기여; bpo-9424.)
assertDictContainsSubset()메서드는 인수가 잘못된 순서로 구현되어 폐지되었습니다. 이로 인해TestCase().assertDictContainsSubset({'a':1, 'b':2}, {'a':1})와 같은 테스트가 실패하는 디버깅하기 어려운 착시 효과가 발생했습니다.(Raymond Hettinger 작성.)
random¶
random 모듈의 정수 메서드들이 이제 균일 분포를 더 잘 생성하도록 개선되었습니다. 이전에는 n 이 2의 거듭제곱이 아닐 때 약간의 편향을 갖는 int(n*random()) 으로 선택 값을 계산했습니다. 이제, 다음 2의 거듭제곱까지 범위에서 여러 번 선택을 수행하며, 해당 선택 값이 0 <= x < n 범위 내에 있을 때만 유지됩니다. 영향을 받는 함수 및 메서드는 randrange(), randint(), choice(), shuffle() 및 sample() 입니다.
(Raymond Hettinger 기여; bpo-9025.)
poplib¶
POP3_SSL 클래스는 이제 context 매개변수를 받습니다. 이 매개변수는 SSL 설정 옵션, 인증서 및 개인 키를 단일(잠재적으로 장수용) 구조로 묶을 수 있는 ssl.SSLContext 객체입니다.
(Giampaolo Rodolà 기여; bpo-8807.)
asyncore¶
asyncore.dispatcher`는 이제 실제 원격 엔드포인트와 연결이 수립되었을 때 호출되는, ``(sock, addr)` 쌍을 반환하는 handle_accepted() 메서드를 제공합니다. 이 메서드는 이전의 handle_accept`를 대체하기 위한 것이며 사용자가 :meth:()!accept`를 직접 호출하는 것을 방지합니다.
(Giampaolo Rodolà 기여; bpo-6706.)
임시 파일¶
tempfile 모듈에는 임시 디렉터리의 쉬운 결정론적 정리(cleanup)를 제공하는 새로운 컨텍스트 관리자인 :class:`~tempfile.TemporaryDirectory`가 추가되었습니다.
with tempfile.TemporaryDirectory() as tmpdirname:
print('created temporary dir:', tmpdirname)
(Neil Schemenauer 및 Nick Coghlan 기여; bpo-5178.)
inspect 메듈¶
inspect모듈에는 제너레이터-이터레이터의 현재 상태를 쉽게 식별할 수 있는 새로운 함수 :func:`~inspect.getgeneratorstate`가 추가되었습니다.>>> from inspect import getgeneratorstate >>> def gen(): ... yield 'demo' ... >>> g = gen() >>> getgeneratorstate(g) 'GEN_CREATED' >>> next(g) 'demo' >>> getgeneratorstate(g) 'GEN_SUSPENDED' >>> next(g, None) >>> getgeneratorstate(g) 'GEN_CLOSED'
(Rodolpho Eckhardt 및 Nick Coghlan 기여, bpo-10220.)
동적 속성 활성화 가능성이 없는 조회를 지원하기 위해,
inspect모듈에 새로운 함수인 :func:`~inspect.getattr_static`이 추가되었습니다. 이는 :func:`hasattr`와 달리 읽기 전용 검색 방식이며, 검색하는 동안 상태가 변경되지 않음을 보장합니다.>>> class A: ... @property ... def f(self): ... print('Running') ... return 10 ... >>> a = A() >>> getattr(a, 'f') Running 10 >>> inspect.getattr_static(a, 'f') <property object at 0x1022bd788>
(Michael Foord 기여.)
pydoc¶
pydoc 모듈은 이제 크게 개선된 웹 서버 인터페이스와, 해당 서버를 표시하기 위해 브라우저 창을 자동으로 열 수 있는 새로운 명령줄 옵션 -b 를 제공합니다.
$ pydoc3.2 -b
(Ron Adam 기여자; bpo-2001.)
dis¶
dis 모듈은 코드 검사를 위한 두 가지 새로운 함수, :func:`~dis.code_info`와 :func:`~dis.show_code`를 얻었습니다. 둘 다 제공된 함수, 메서드, 소스 코드 문자열 또는 코드 객체에 대한 상세한 코드 객체 정보를 제공합니다. 전자는 문자열을 반환하고 후자는 이를 인쇄합니다.
>>> import dis, random
>>> dis.show_code(random.choice)
Name: choice
Filename: /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py
Argument count: 2
Kw-only arguments: 0
Number of locals: 3
Stack size: 11
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
0: 'Choose a random element from a non-empty sequence.'
1: 'Cannot choose from an empty sequence'
Names:
0: _randbelow
1: len
2: ValueError
3: IndexError
Variable names:
0: self
1: seq
2: i
또한, dis() 함수는 이제 문자열 인수를 받게 되어 일반적인 표현식인 dis(compile(s, '', 'eval')) 을 dis(s) 로 단축할 수 있습니다.
>>> dis('3*x+1 if x%2==1 else x//2')
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (2)
6 BINARY_MODULO
7 LOAD_CONST 1 (1)
10 COMPARE_OP 2 (==)
13 POP_JUMP_IF_FALSE 28
16 LOAD_CONST 2 (3)
19 LOAD_NAME 0 (x)
22 BINARY_MULTIPLY
23 LOAD_CONST 1 (1)
26 BINARY_ADD
27 RETURN_VALUE
>> 28 LOAD_NAME 0 (x)
31 LOAD_CONST 0 (2)
34 BINARY_FLOOR_DIVIDE
35 RETURN_VALUE
이러한 개선 사항들을 종합해 보면 CPython이 어떻게 구현되었는지 살펴보고 언어 문법이 내부적으로 무엇을 하는지 직접 확인할 수 있어 더 쉬워졌습니다.
(Nick Coghlan 기여; bpo-9147.)
dbm¶
모든 데이터베이스 모듈이 이제 get() 및 setdefault() 메서드를 지원합니다.
(Ray Allen 제시; bpo-9523.)
ctypes¶
새로운 타입인 ctypes.c_ssize_t`는 C :c:type:`ssize_t 데이터형을 나타냅니다.
site¶
site 모듈은 주어진 Python 설치의 세부 정보를 보고하는 데 유용한 세 가지 새로운 함수를 제공합니다.
:func:`~site.getsitepackages`는 모든 전역 site-packages 디렉터리를 나열합니다.
:func:`~site.getuserbase`는 데이터를 저장할 수 있는 사용자의 기본 디렉터리 정보를 보고합니다.
:func:`~site.getusersitepackages`는 사용자별 site-packages 디렉터리 경로를 보여줍니다.
>>> import site
>>> site.getsitepackages()
['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',
'/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',
'/Library/Python/3.2/site-packages']
>>> site.getuserbase()
'/Users/raymondhettinger/Library/Python/3.2'
>>> site.getusersitepackages()
'/Users/raymondhettinger/Library/Python/3.2/lib/python/site-packages'
편의상, `site`의 일부 기능은 명령줄에서 직접 액세스할 수 있습니다:
$ python -m site --user-base
/Users/raymondhettinger/.local
$ python -m site --user-site
/Users/raymondhettinger/.local/lib/python3.2/site-packages
(Tarek Ziadé 기여; bpo-6693.)
sysconfig 모듈¶
새로운 sysconfig 모듈은 플랫폼 및 설치에 따라 달라지는 설치 경로와 구성 변수를 쉽게 찾을 수 있도록 합니다.
이 모듈은 플랫폼 및 버전 정보에 대한 단순한 액세스 함수들을 제공합니다:
linux-i586 또는 macosx-10.6-ppc 와 같은 값을 반환하는
get_platform().:func:`~sysconfig.get_python_version`은 “3.2”와 같은 Python 버전 문자열을 반환합니다.
또한 distutils 에서 사용되는 일곱 개의 명명된 스킴에 해당하는 경로와 변수에 액세스할 수도 있습니다. 여기에는 posix_prefix, posix_home, posix_user, nt_, nt_user, os2_, os2_home 이 포함됩니다.
get_paths()는 현재 설치 스킴에 대한 설치 경로를 담고 있는 딕셔너리를 반환합니다.get_config_vars()는 플랫폼별 변수들의 딕셔너리를 반환합니다.
또한 편리한 명령줄 인터페이스가 있습니다.
C:\Python32>python -m sysconfig
Platform: "win32"
Python version: "3.2"
Current installation scheme: "nt"
Paths:
data = "C:\Python32"
include = "C:\Python32\Include"
platinclude = "C:\Python32\Include"
platlib = "C:\Python32\Lib\site-packages"
platstdlib = "C:\Python32\Lib"
purelib = "C:\Python32\Lib\site-packages"
scripts = "C:\Python32\Scripts"
stdlib = "C:\Python32\Lib"
Variables:
BINDIR = "C:\Python32"
BINLIBDEST = "C:\Python32\Lib"
EXE = ".exe"
INCLUDEPY = "C:\Python32\Include"
LIBDEST = "C:\Python32\Lib"
SO = ".pyd"
VERSION = "32"
abiflags = ""
base = "C:\Python32"
exec_prefix = "C:\Python32"
platbase = "C:\Python32"
prefix = "C:\Python32"
projectbase = "C:\Python32"
py_version = "3.2"
py_version_nodot = "32"
py_version_short = "3.2"
srcdir = "C:\Python32"
userbase = "C:\Documents and Settings\Raymond\Application Data\Python"
(Tarek Ziadé에 의해 Distutils에서 제외됨.)
pdb¶
pdb 디버거 모듈은 사용성 개선 사항이 많이 추가되었습니다.
pdb.py에는 이제-c옵션이 있어.pdbrc스크립트 파일에 주어진 명령을 실행할 수 있습니다..pdbrc스크립트 파일은 디버깅을 계속하는continue및next명령을 포함할 수 있습니다.Pdb클래스 생성자는 이제 nosigint 인수를 받습니다.새로운 명령:
l(list),ll(long list)및 소스 코드를 나열하기 위한source.새로운 명령: 표현식의 값이 변경되었을 경우 그 값을 보여주거나 숨기는
display``와 ``undisplay.새로운 명령: 현재 범위에서 발견된 전역 및 지역 이름을 포함하는 대화형 인터프리터를 시작하는
interact.중단점은 중단점 번호로 지울 수 있습니다.
(Georg Brandl, Antonio Cuni 및 Ilya Sandler가 기여됨.)
configparser¶
configparser 모듈은 사용성과 예측 가능성을 개선하기 위해 기본 구문 분석기 및 지원되는 INI 문법을 수정했습니다. 이전 ConfigParser 클래스는 :class:`!SafeConfigParser`로 제거되었으며, 이는 다시 :class:`~configparser.ConfigParser`로 이름이 변경되었습니다. 인라인 주석 지원은 이제 기본적으로 비활성화되며 단일 구성 소스에서 섹션 또는 옵션 중복을 허용하지 않습니다.
구성 분석기에 매핑 프로토콜을 기반으로 하는 새로운 API가 추가되었습니다:
>>> parser = ConfigParser()
>>> parser.read_string("""
... [DEFAULT]
... location = upper left
... visible = yes
... editable = no
... color = blue
...
... [main]
... title = Main Menu
... color = green
...
... [options]
... title = Options
... """)
>>> parser['main']['color']
'green'
>>> parser['main']['editable']
'no'
>>> section = parser['options']
>>> section['title']
'Options'
>>> section['title'] = 'Options (editable: %(editable)s)'
>>> section['title']
'Options (editable: no)'
새로운 API는 클래식 API 위에 구현되므로, 사용자 정의 파서 하위 클래스는 수정 없이 이를 사용할 수 있어야 합니다.
구성 분석기가 허용하는 INI 파일 구조를 이제 사용자 정의할 수 있습니다. 사용자는 대체 옵션/값 구분자 및 주석 접두사를 지정하고, DEFAULT 섹션의 이름을 변경하거나 보간 구문을 전환할 수 있습니다.
추가적인 보간 핸들러인 :class:`~configparser.ExtendedInterpolation`을 포함하여 플러거블한 보간 지원이 가능합니다:
>>> parser = ConfigParser(interpolation=ExtendedInterpolation())
>>> parser.read_dict({'buildout': {'directory': '/home/ambv/zope9'},
... 'custom': {'prefix': '/usr/local'}})
>>> parser.read_string("""
... [buildout]
... parts =
... zope9
... instance
... find-links =
... ${buildout:directory}/downloads/dist
...
... [zope9]
... recipe = plone.recipe.zope9install
... location = /opt/zope
...
... [instance]
... recipe = plone.recipe.zope9instance
... zope9-location = ${zope9:location}
... zope-conf = ${custom:prefix}/etc/zope.conf
... """)
>>> parser['buildout']['find-links']
'\n/home/ambv/zope9/downloads/dist'
>>> parser['instance']['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance = parser['instance']
>>> instance['zope-conf']
'/usr/local/etc/zope.conf'
>>> instance['zope9-location']
'/opt/zope'
또한 읽기 작업에서 인코딩 지정, get 함수에 대한 폴백 값 지정, 또는 딕셔너리 및 문자열에서 직접 읽기 등의 여러 작은 기능들이 도입되었습니다.
(Łukasz Langa가 모든 변경 사항을 기여함.)
urllib.parse¶
urllib.parse 모듈에 여러 사용성 개선 사항이 적용되었습니다.
urlparse() 함수는 이제 RFC 2732 에서 설명하는 IPv6 주소를 지원합니다:
>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
ParseResult(scheme='http',
netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
path='/foo/',
params='',
query='',
fragment='')
urldefrag() 함수는 이제 :term:`named tuple`을 반환합니다:
>>> r = urllib.parse.urldefrag('http://python.org/about/#target')
>>> r
DefragResult(url='http://python.org/about/', fragment='target')
>>> r[0]
'http://python.org/about/'
>>> r.fragment
'target'
그리고, urlencode() 함수는 query 인수에 문자열 또는 바이트 유형 중 하나를 받아들여 훨씬 더 유연해졌습니다. 만약 이것이 문자열이라면, safe, encoding, 및 error 매개변수는 인코딩을 위해 :func:`~urllib.parse.quote_plus`로 전송됩니다:
>>> urllib.parse.urlencode([
... ('type', 'telenovela'),
... ('name', '¿Dónde Está Elisa?')],
... encoding='latin-1')
'type=telenovela&name=%BFD%F3nde+Est%E1+Elisa%3F'
parsing-ascii-encoded-bytes`에서 자세히 설명했듯이, 모든 :mod:`urllib.parse 함수는 이제 일반 문자열과 혼합되어 있지 않은 한 ASCII 인코딩된 바이트 문자열을 입력으로 받으며, 만약 매개변수로 ASCII 인코딩된 바이트 문자열이 주어지면 반환 유형 또한 ASCII 인코딩된 바이트 문자열이 됩니다:
>>> urllib.parse.urlparse(b'http://www.python.org:80/about/')
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
path=b'/about/', params=b'', query=b'', fragment=b'')
(Nick Coghlan, Dan Mahn 및 Senthil Kumaran가 bpo-2987, bpo-5468 및 :issue:`9873`에서 작업함.)
mailbox¶
Thanks to a concerted effort by R. David Murray, the mailbox module has
been fixed for Python 3.2. The challenge was that mailbox had been originally
designed with a text interface, but email messages are best represented with
bytes because various parts of a message may have different encodings.
이 솔루션은 임의의 이메일 메시지를 구문 분석하기 위해 email 패키지의 바이너리 지원을 활용했습니다. 게다가, 이 솔루션에는 여러 API 변경 사항이 필요했습니다.
예상대로, mailbox.Mailbox 객체용 add() 메서드는 이제 바이너리 입력을 허용합니다.
StringIO 및 텍스트 파일 입력은 지원이 중단되었습니다. 또한, 문자열 입력은 비-ASCII 문자가 사용될 경우 조기에 실패할 수 있습니다. 이전에는 나중에 이메일이 처리될 때 실패했습니다.
바이너리 출력도 지원됩니다. get_file() 메서드는 이제 바이너리 모드로 파일을 반환합니다 (이전에는 실수로 텍스트 모드로 설정했습니다). 또한, 주어진 key 에 해당하는 메시지의 bytes 표현을 반환하는 새로운 get_bytes() 메서드도 있습니다.
오래된 API의 get_string() 메서드를 사용하여 여전히 비바이너리 출력을 얻는 것은 가능하지만, 그 접근 방식은 그다지 유용하지 않습니다. 대신, Message 객체에서 메시지를 추출하거나 바이너리 입력에서 로드하는 것이 가장 좋습니다.
(R. David Murray가 기여하고, Steffen Daode Nurpmeso가 노력했으며, Victor Stinner가 :issue:`9124`를 통해 초기 패치를 적용했습니다.)
turtledemo¶
turtle 모듈의 데모 코드가 Demo 디렉토리에서 주 라이브러리로 이동되었습니다. 열두 개가 넘는 역동적인 디스플레이를 가진 샘플 스크립트들을 포함하고 있습니다. :data:`sys.path`에 있기 때문에 이제 명령줄에서 직접 실행할 수 있습니다.
$ python -m turtledemo
(Alexander Belopolsky가 :issue:`10199`를 통해 Demo 디렉토리에서 이동했습니다.)
다중 스레드¶
동시에 실행되는 Python 스레드의 실행을 직렬화하는 메커니즘(일반적으로 GIL 또는 Global Interpreter Lock으로 알려짐)이 재작성되었습니다. 목표 중 일부는 더 예측 가능한 전환 간격과 락 경합 및 후속 시스템 호출 수로 인한 오버헤드 감소였습니다. 스레드 전환을 허용하는 “체크 간격”의 개념은 포기되었고, 초 단위로 표현된 절대 지속 시간으로 대체되었습니다. 이 매개변수는 :func:`sys.setswitchinterval`를 통해 조정할 수 있습니다. 현재 기본값은 5 밀리초입니다.
구현에 대한 추가 세부 정보는 `python-dev 메일링 리스트 <https://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_(다만, 이 메시지에 노출된 “우선순위 요청 사항”은 포함되지 않았습니다.)에서 읽을 수 있습니다.
(Antoine Pitrou가 기여했습니다.)
정규 및 재귀 락은 이제
acquire()메서드에 선택적 timeout 인자를 받습니다. (Antoine Pitrou 기여; bpo-7316.)유사하게,
threading.Semaphore.acquire`도 *timeout* 인자를 갖게 되었습니다. (Torsten Landschoff 기여; :issue:`850728().)정규 및 재귀 잠금 확보는 Pthreads를 사용하는 플랫폼에서 신호에 의해 중단될 수 있습니다. 이는 락을 확보하는 동안 교착 상태가 발생하는 Python 프로그램도 프로세스에 SIGINT를 반복적으로 보내서 성공적으로 종료할 수 있음을 의미합니다 (대부분의 셸에서 Ctrl+C`를 눌러). (Reid Kleckner 기여; :issue:`8844.)
최적화들`¶
다수의 작은 성능 향상이 추가되었습니다:
Python의 피홀 옵티마이저는 이제 `x in {1, 2, 3}`과 같은 패턴을 상수 집합에 대한 멤버십 검사로 인식합니다. 옵티마이저는 :class:`set`을 :class:`frozenset`으로 재캐스팅하고 사전 구축된 상수를 저장합니다.
이제 속도 페널티가 사라졌으므로, set-notion(집합 표기법)을 사용하여 멤버십 테스트를 작성하는 것이 실용적입니다. 이 스타일은 의미적으로 명확하고 운영적으로 빠릅니다:
extension = name.rpartition('.')[2] if extension in {'xml', 'html', 'xhtml', 'css'}: handle(name)
(Dave Malcolm가 패치 및 추가 테스트 기여; bpo-6690).
pickle모듈을 사용하여 데이터를 직렬화하고 역직렬화하는 것이 이제 몇 배 더 빨라졌습니다.(Alexandre Vassalotti, Antoine Pitrou 및 Unladen Swallow 팀이 :issue:`9410`과 :issue:`3873`에 기여했습니다.)
The Timsort algorithm used in
list.sort()andsorted()now runs faster and uses less memory when called with a key function. Previously, every element of a list was wrapped with a temporary object that remembered the key value associated with each element. Now, two arrays of keys and values are sorted in parallel. This saves the memory consumed by the sort wrappers, and it saves time lost to delegating comparisons.(Daniel Stutzbach가 :issue:`9915`에 패치함.)
같은 문자열이 여러 키에 반복되는 경우 JSON 디코딩 성능이 향상되고 메모리 사용량이 감소합니다. 또한, sort_keys 인수가 참일 때 JSON 인코딩은 C 속도 향상을 사용합니다.
(Antoine Pitrou가 :issue:`7451`에, 그리고 Raymond Hettinger와 Antoine Pitrou가 :issue:`10314`에 기여함.)
재귀적 록(
threading.RLock()API로 생성)은 이제 C 구현의 이점을 얻어 일반 록만큼 빠르며, 이전 순수 Python 구현보다 10배에서 15배 더 빠릅니다.(Antoine Pitrou 기여; bpo-3001.)
bytes,bytearray, 및str객체의split(),rsplit(),splitlines(), 그리고replace()메서드에서 문자열 lib의 빠른 검색 알고리즘이 사용됩니다. 마찬가지로, 해당 알고리즘은rfind(),rindex(),rsplit(), 및 :meth:`~str.rpartition`에서도 사용됩니다.정수에서 문자열로의 변환이 이제 두 “자릿수”씩 작동하여 나누기 및 모듈로 연산 횟수를 줄였습니다.
(bpo-6713 Gawain Bolton, Mark Dickinson, 그리고 Victor Stinner.)
다른 몇 가지 사소한 최적화가 있었습니다. 이제 연산자 중 하나가 다른 하나보다 훨씬 클 경우 집합 차집합 계산이 더 빨리 실행됩니다 (Andress Bennetts가 bpo-8685 에서 패치함). array.repeat() 메서드는 더 빠른 구현을 가집니다 (bpo-1569291 Alexander Belopolsky 기여). BaseHTTPRequestHandler 는 더욱 효율적인 버퍼링을 갖습니다 (bpo-3709 Andrew Schaaf 기여). operator.attrgetter() 함수가 속도 향상되었습니다 (bpo-10160 Christos Georgiou 기여). 또한 ConfigParser 는 다중 라인 인수를 약간 더 빨리 로드합니다 (bpo-7113 Łukasz Langa 기여).
유니코드(Unicode)¶
Python이 Unicode 6.0.0 <https://unicode.org/versions/Unicode6.0.0/>`_으로 업데이트되었습니다. 표준에 대한 업데이트에는 모바일 휴대폰에 중요한 `emoji 기호를 포함하여 2,000개가 넘는 새로운 문자가 추가되었습니다.
게다가, 업데이트된 표준은 두 개의 칸나다 문자(U+0CF1, U+0CF2)와 하나의 신 타이 루어 숫자 문자(U+19DA)에 대한 문자 속성을 변경하여, 전자는 식별자에서 사용이 가능하게 하고 후자는 사용할 수 없게 만들었습니다. 더 자세한 내용은 `Unicode Character Database Changes <https://www.unicode.org/versions/Unicode6.0.0/#Database_Changes>`_를 참조하세요.
코덱¶
cp720 아랍어 DOS 인코딩에 대한 지원이 추가되었습니다 (bpo-1616979).
MBCS 인코딩은 더 이상 에러 핸들러 인수를 무시하지 않습니다. 기본 엄격 모드에서, 디코딩 시 디코드할 수 없는 바이트 순서를 만나면 :exc:`UnicodeDecodeError`를 발생시키고 인코딩할 수 없는 문자에 대해서는 :exc:`UnicodeEncodeError`를 발생시킵니다.
MBCS 코덱은 디코딩을 위한 'strict' 및 'ignore' 에러 핸들러와 인코딩을 위한 'strict' 및 'replace' 를 지원합니다.
Python 3.1 MBCS 인코딩을 에뮬레이션하려면, 디코딩에는 'ignore' 핸들러를, 인코딩에는 'replace' 핸들러를 선택하세요.
Mac OS X에서 Python은 로케일 인코딩 대신 'utf-8' 을 사용하여 명령줄 인수를 디코드합니다.
기본적으로 tarfile`은 Windows에서 `’utf-8’`` 인코딩('mbcs'` 대신)을 사용하며, 모든 운영 체제에서 ``'surrogateescape' 에러 핸들러를 사용합니다.
문서화¶
문서는 지속적으로 개선되고 있습니다.
A table of quick links has been added to the top of lengthy sections such as 내장 함수. In the case of
itertools, the links are accompanied by tables of cheatsheet-style summaries to provide an overview and memory jog without having to read all of the docs.일부 경우에는 순수 Python 소스 코드가 문서에 유용한 보조 자료가 될 수 있으므로, 이제 많은 모듈에서 최신 버전 소스 코드에 대한 빠른 링크를 제공합니다. 예를 들어,
functools모듈 설명서 상단에 다음 레이블의 빠른 링크가 있습니다:소스 코드: Lib/functools.py.
(Raymond Hettinger 기고; rationale <https://rhettinger.wordpress.com/2011/01/28/open-your-source-more/>_ 참조.)
문서에 더 많은 예제와 조리법이 포함되었습니다. 특히,
re모듈에는 광범위한 섹션인 re-examples`가 있습니다. 마찬가지로, :mod:`itertools 모듈은 새로운 :ref:`itertools-recipes`와 함께 지속적으로 업데이트되고 있습니다.datetime모듈에는 이제 순수 Python으로 작성된 보조 구현이 있습니다. 기능 변경은 없었습니다. 이것은 단지 더 읽기 쉬운 대체 구현을 제공하는 것입니다.(Alexander Belopolsky가 :issue:`9528`에 기여했습니다.)
사용되지 않는
Demo디렉토리가 제거되었습니다. 일부 데모는 문서에 통합되었고, 일부는Tools/demo디렉토리로 이동했으며, 나머지는 완전히 제거되었습니다.(Georg Brandl이 :issue:`7962`에 기여했습니다.)
IDLE¶
코드 저장소¶
기존의 :https://svn.python.org/ 에 있는 Subversion 코드 저장소 외에도, 이제 https://hg.python.org/에 Mercurial <https://www.mercurial-scm.org/>_ 저장소가 있습니다.
3.2 버전 릴리스 이후, 기본 저장소를 Mercurial로 전환할 계획이 있습니다. 이 분산형 버전 관리 시스템은 커뮤니티 구성원들이 외부 변경셋을 더 쉽게 생성하고 공유할 수 있도록 할 것입니다. 자세한 내용은 :pep:`385`를 참조하십시오.
새로운 버전 관리 시스템 사용법을 알아보려면 Quick Start <https://www.mercurial-scm.org/wiki/QuickStart>_ 또는 Guide to Mercurial Workflows <https://www.mercurial-scm.org/guide>_를 참조하십시오.
빌드 및 C API 변경 사항¶
파이썬의 빌드 프로세스와 C API에 대한 변경 사항은 다음과 같습니다:
idle, pydoc, 및 2to3 스크립트는 이제
make altinstall에서 버전별 접미사로 설치됩니다 (bpo-10679).유니코드 데이터베이스에 접근하는 C 함수들은 이제 좁은 유니코드 빌드에서도 전체 유니코드 범주의 문자를 받아들이고 반환합니다 (Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL 등). Python에서 눈에 띄는 차이점은 :func:`unicodedata.numeric`가 이제 큰 코드 포인트에 대한 올바른 값을 반환하고, :func:`repr`이 더 많은 문자를 인쇄 가능한 것으로 간주할 수 있다는 것입니다.
(Bupjoe Lee가 보고하고 Amaury Forgeot D’Arc가 수정했습니다; bpo-5127.)
계산된 gotos는 이제 지원되는 컴파일러에서 기본적으로 활성화됩니다 (configure 스크립트에서 감지됨). 여전히
--without-computed-gotos를 지정하여 선택적으로 비활성화할 수 있습니다.(Antoine Pitrou가 :issue:`9203`에 기여했습니다.)
--with-wctype-functions옵션이 제거되었습니다. 이제 내장 유니코드 데이터베이스가 모든 함수에 사용됩니다.(Amaury Forgeot D’Arc가 :issue:`9210`에 기여했습니다.)
해시 값은 이제 새 유형인
Py_hash_t의 값이 되었으며, 이 타입은 포인터와 동일한 크기로 정의되었습니다. 이전에는 long 타입이었는데, 일부 64비트 운영체제에서는 여전히 32비트에 불과했습니다. 이 수정으로 인해,set및dict는 이제 64비트 포인터를 사용하는 빌드에서2**32개의 항목을 담을 수 있게 되었습니다 (이전에는 그 크기까지 증가할 수 있었지만 성능이 치명적으로 저하되었습니다).(Raymond Hettinger가 제안하고 Benjamin Peterson가 구현했습니다; bpo-9778.)
새로운 매크로
Py_VA_COPY`는 가변 인자 목록의 상태를 복사합니다. 이는 C99 *va_copy*와 등가이지만 모든 Python 플랫폼에서 사용할 수 있습니다 (:issue:`2443).A new C API function
PySys_SetArgvEx()allows an embedded interpreter to setsys.argvwithout also modifyingsys.path(bpo-5753).PyEval_CallObject`는 이제 매크로 형태로만 사용할 수 있습니다. 이전에 하위 호환성을 위해 유지되었던 함수 선언은 제거되었습니다 -- 해당 매크로는 1997년에 도입되었습니다 (:issue:`8276()).PyLong_AsLongLongAndOverflow()라는 새로운 함수가 존재하며, 이는PyLong_AsLongAndOverflow()와 유사합니다. 둘 다 Pythonint를 기본 고정 너비 형식으로 변환하는 기능을 수행하며, 변환이 맞지 않는 경우를 감지할 수 있게 합니다 (bpo-7767).PyUnicode_CompareWithASCIIString()함수는 이제 Python 문자열이 NUL 로 종료된 경우 같지 않음 (not equal)을 반환합니다.새로운 함수
PyErr_NewExceptionWithDoc()는PyErr_NewException()과 같지만, 독스트링을 지정할 수 있게 합니다. 이를 통해 C 예외가 순수 Python 대응자와 동일한 자체 문서화 기능을 갖게 됩니다 (bpo-7033).--with-valgrind옵션으로 컴파일할 때, pymalloc 할당자는 Valgrind에서 실행되는 동안 자동으로 비활성화됩니다. 이는 Valgrind에서 실행 시 메모리 누수 감지를 개선하며, 다른 시간에는 pymalloc의 이점을 활용합니다 (bpo-2422).PyArg_Parse 함수들에서
O?형식을 제거했습니다. 이 형식은 더 이상 사용되지 않으며 문서화 된 적이 없습니다 (bpo-8837).
C-API 측면에서 다른 몇 가지 작은 변경 사항들이 있었습니다. 전체 목록은 Misc/NEWS 파일을 확인해 주십시오.
또한, Mac OS X 빌드에 여러 업데이트가 있었습니다. 자세한 내용은 `Mac/BuildScript/README.txt <https://github.com/python/cpython/blob/v3.2.6/Mac/BuildScript/README.txt>`_을 확인하십시오. 32/64비트 빌드를 사용하는 사용자의 경우, Mac OS X 10.6의 기본 Tcl/Tk에 알려진 문제가 있습니다. 이에 따라 `ActiveState Tcl/Tk 8.5.9 <https://web.archive.org/web/20101208191259/https://www.activestate.com/activetcl/downloads>`와 같은 업데이트된 대안을 설치할 것을 권장합니다. 추가 세부 정보는 https://www.python.org/download/mac/tcltk/에서 확인하십시오.
Python 3.2로 이식하기¶
본 섹션은 코드 변경이 필요할 수 있는 이전에 설명한 변경 사항과 기타 버그 수정 사항을 나열합니다:
configparser모듈에는 여러 가지 정리 작업이 있었습니다. 주요 변경 사항은 오래된ConfigParser클래스를 오랫동안 선호되어 온 대안인 :class:`!SafeConfigParser`로 대체하는 것입니다. 이 외에도 몇 가지 사소한 비호환성 문제가 있습니다:이제 보간 구문은
get()및set()작업에서 검증됩니다. 기본 보간 방식에서는 백분율 기호가 있는 두 개의 토큰(“%(name)s”와 “%%”)만 유효합니다. 후자는 이스케이프된 백분율 기호입니다.set()및add_section()메서드는 이제 값이 실제 문자열인지 확인합니다. 이전에는 지원되지 않는 유형이 의도치 않게 도입될 수 있었습니다.단일 소스로부터 가져온 중복된 섹션이나 옵션은 이제
DuplicateSectionError또는DuplicateOptionError예외를 발생시킵니다. 이전에는 중복 항목이 이전 항목을 조용히 덮어썼습니다.이제 인라인 주석은 기본적으로 비활성화되어 ; 문자를 값에서 안전하게 사용할 수 있게 되었습니다.
주석이 들여쓰기 될 수 있습니다. 결과적으로, 여러 줄 값의 시작 부분에 ; 또는 # 가 나타나려면 보간되어야 합니다. 이렇게 함으로써 값이 안에 있는 주석 접두사 문자가 주석으로 오인되는 것을 방지합니다.
""는 이제 유효한 값이며 더 이상 빈 문자열로 자동으로 변환되지 않습니다. 빈 문자열을 사용하려면 줄에"option ="를 사용하십시오.
nntplib모듈은 광범위하게 재작업되었기 때문에, 그 API는 3.1 API와 자주 비호환적입니다.bytearray객체는 더 이상 파일 이름으로 사용될 수 없으며, 대신 :class:`bytes`로 변환해야 합니다.가독성을 높이기 위해
array.tostring()및array.fromstring`은 각각 :meth:`array.tobytes() <array.array.tobytes>`와 :meth:`array.frombytes() <array.array.frombytes>`로 이름이 변경되었습니다. 구 버전 이름들은 사용 중지되었습니다. (참조: :issue:`8990().)PyArg_Parse*()함수들:“t#”” 포맷은 제거되었습니다. 대신 “s#” 또는 “s*”를 사용하십시오.
“w” 및 “w#” 포맷이 제거되었습니다. 대신 “w*””을 사용하십시오.
PyCObject타입은 3.1 버전에서 사용 중지되었으며, 제거되었습니다. Python 객체 내의 불투명한 C 포인터를 감싸기 위해서는 대신PyCapsuleAPI를 사용해야 합니다. 새로운 타입은 타이핑 안전성 정보를 전달하는 잘 정의된 인터페이스와 소멸자를 호출하기 위한 덜 복잡한 서명을 가지고 있습니다.sys.setfilesystemencoding()함수는 결함 있는 설계로 인해 제거되었습니다.이제
random.seed()함수와 메서드는 sha512 해시 함수를 사용하여 문자열 시드에 솔트(salt)를 적용합니다. Python 3.1 시퀀스를 재현하기 위해 seed 의 이전 버전을 사용하려면, version 인수를 1 로 설정하십시오.random.seed(s, version=1).이전에 사용 중지되었던
string.maketrans()함수는 대신 정적 메서드인bytes.maketrans`와 :meth:`bytearray.maketrans`를 사용하게 되었습니다. 이 변경은 어떤 타입이 :mod:`string()모듈에서 지원되었는지에 대한 혼란을 해결합니다. 이제,str,bytes, 그리고bytearray각각은 적절한 타입을 가진 중간 번역 테이블을 지닌 자체 maketrans 및 translate 메서드를 가지고 있습니다.(Georg Brandl 기여; bpo-5675.)
이전에 사용 중지되었던
contextlib.nested()함수는 여러 컨텍스트 관리자를 허용하는 일반적인with문으로 대체되었습니다. 후자는 더 빠르며 (내장되어 있기 때문에), 그중 하나가 예외를 발생시킬 때 여러 컨텍스트 관리자를 마무리하는 작업을 더 잘 수행합니다:with open('mylog.txt') as infile, open('a.out', 'w') as outfile: for line in infile: if '<critical>' in line: outfile.write(line)
(Georg Brandl 및 Mattias Brändström 기여; appspot issue 53094.)
:func:`struct.pack`은 이제 “s” 문자열 패킹 코드에 대해 바이트만 허용합니다. 이전에 시스템에서는 텍스트 인자를 받아 UTF-8을 사용해 암묵적으로 바이트로 인코딩했습니다. 이는 올바른 인코딩에 대한 가정을 했고, 가변 길이 인코딩이 구조체의 고정 길이 영역에 쓰기 할 때 실패할 수 있었기 때문에 문제가 되었습니다.
struct.pack('<6sHHBBB', 'GIF87a', x, y)같은 코드는 텍스트 대신 바이트를 사용하도록 다음과 같이 다시 작성되어야 합니다.`struct.pack('<6sHHBBB', b'GIF87a', x, y)”.(David Beazley가 발견하고 Victor Stinner가 수정; bpo-10783.)
xml.etree.ElementTree클래스는 이제 구문 분석에 실패할 때 :exc:`xml.etree.ElementTree.ParseError`를 발생시킵니다. 이전에는 :exc:`xml.parsers.expat.ExpatError`를 발생시켰습니다.플로트에 대한 새롭고 긴
str()값은 구 버전 출력 형식을 신뢰하는 doctest를 깨뜨릴 수 있습니다.subprocess.Popen에서 close_fds 의 기본값은 이제 유닉스 환경에서True이고; 윈도우에서는 세 표준 스트림이None으로 설정된 경우에만True이며, 그렇지 않은 경우에는False입니다. 이전에는 close_fds 가 항상 기본적으로False였기 때문에, 열린 파일 디스크립터가 자식 프로세스로 누설될 때 해결하기 어려운 버그나 경쟁 조건이 발생했습니다.:mod:`urllib.request`와 :mod:`http.client`에서 레거시 HTTP 0.9 지원이 제거되었습니다. 이러한 지원은 서버 측( :mod:`http.server`에서)에서는 여전히 남아 있습니다.
(Antoine Pitrou 기여, bpo-10711.)
타임아웃 모드의 SSL 소켓은 타임아웃이 발생할 때 일반적인
SSLError대신 :exc:`socket.timeout`를 발생시킵니다.(Antoine Pitrou 기여, bpo-10272.)
오해의 소지가 있는 함수인
PyEval_AcquireLock`와 :c:func:()!PyEval_ReleaseLock`은 공식적으로 사용 중지되었습니다. 대신 스레드 상태를 아는 API (예:PyEval_SaveThread()및PyEval_RestoreThread())를 사용해야 합니다.보안상의 위험으로 인해
asyncore.handle_accept`는 제거되었고, 이를 대체하기 위해 새로운 함수인 :func:()!asyncore.handle_accepted`가 추가되었습니다.(Giampaolo Rodola가 :issue:`6706`에서 기여했습니다.)
새로운 GIL 구현으로 인해, 더 이상
Py_Initialize()\를 호출하기 전에 :c:func:`!PyEval_InitThreads`를 호출할 수 없습니다.