Python 2.4에 새로 추가된 기능¶
- 저자:
A.M. Kuchling
이 문서는 2005년 3월 30일에 출시된 Python 2.4.1의 새로운 기능을 설명합니다.
Python 2.4는 중규모 배포판입니다. 근본적인 Python 2.2만큼 많은 변화를 소개하지는 않지만, 보수적인 2.3 배포판보다 더 많은 기능을 도입합니다. 가장 중요한 새로운 언어 기능은 함수 데코레이터와 제너레이터 표현식이며; 다른 대부분의 변경 사항은 표준 라이브러리에 관한 것입니다.
CVS 변경 로그에 따르면, Python 2.3과 2.4 사이에 481개의 패치가 적용되었고 502개의 버그가 수정되었습니다. 두 수치 모두 과소평가일 가능성이 높습니다.
This article doesn’t attempt to provide a complete specification of every single new feature, but instead provides a brief introduction to each feature. For full details, you should refer to the documentation for Python 2.4, such as the Python Library Reference and the Python Reference Manual. Often you will be referred to the PEP for a particular new feature for explanations of the implementation and design rationale.
PEP 218: 내장 집합 객체 (Built-In Set Objects)¶
Python 2.3에서 sets 모듈이 도입되었습니다. 세트 자료형 C 구현은 이제 두 가지 새로운 내장 타입, set(iterable) 과 frozenset(iterable) 로 Python 핵심에 추가되었습니다. 이들은 멤버십 테스트, 시퀀스에서 중복 항목 제거, 그리고 합집합, 교집합, 차집합, 대칭 차집합과 같은 수학적 연산을 위한 빠른 속도의 기능을 제공합니다.
>>> a = set('abracadabra') # 문자열로 세트를 생성합니다
>>> 'z' in a # 빠른 멤버십 테스트
False
>>> a # a의 고유한 글자들
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a) # 다시 문자열로 변환합니다
'arbcd'
>>> b = set('alacazam') # 두 번째 세트를 생성합니다
>>> a - b # a에 있지만 b에는 없는 글자들
set(['r', 'd', 'b'])
>>> a | b # a 또는 b 중 어느 것의 글자들 모두
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # a와 b에 모두 있는 글자들
set(['a', 'c'])
>>> a ^ b # a 또는 b 중 어느 것의 글자이면서 양쪽 모두에는 없는 경우
set(['r', 'd', 'b', 'm', 'z', 'l'])
>>> a.add('z') # 새로운 요소를 추가합니다
>>> a.update('wxy') # 여러 새로운 요소를 업데이트합니다
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x') # 하나의 요소를 제거합니다
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])
frozenset() 타입은 :func:`set`의 불변 버전입니다. 불변하고 해시 가능(hashable) 하므로, 딕셔너리 키로 사용하거나 다른 세트의 원소로 사용할 수 있습니다.
sets 모듈은 표준 라이브러리에 남아 있으며, 만약 Set 또는 ImmutableSet 클래스를 서브클래스하고 싶다면 유용할 수 있습니다. 현재로서는 이 모듈을 사용 중단(deprecate)할 계획이 없습니다.
더 보기
- PEP 218 - 내장 집합 객체 유형 추가
원래 Greg Wilson이 제안했고 Raymond Hettinger가 최종적으로 구현했습니다.
PEP 237: Long Integers와 Integer의 통일화 (Unifying Long Integers and Integers)¶
Python 2.2에서 시작된 이 PEP의 긴 전환 과정이 Python 2.4에서 한 단계 더 발전했습니다. 2.3 버전에서는 int/long 통일화 후 동작 방식이 다르게 작동할 수 있는 특정 정수 연산이 FutureWarning 경고를 유발했으며, 반환 값은 (플랫폼에 따라) 32비트 또는 64비트로 제한되었습니다. 2.4 버전에서는 이러한 표현식이 더 이상 경고를 발생시키지 않고 대신 일반적으로 long 정수인 다른 결과를 생성합니다.
문제가 되는 표현식은 주로 왼쪽 시프트(left shifts) 및 긴 16진수/8진수 상수입니다. 예를 들어, 2 << 32 는 2.3 버전에서 32비트 플랫폼에서는 0으로 평가되는 경고를 유발합니다. Python 2.4에서는 이 표현식이 올바른 값인 8589934592를 반환합니다.
더 보기
- PEP 237 - Long Integers와 Integer의 통일화 (Unifying Long Integers and Integers)
원래 PEP는 Moshe Zadka와 GvR이 작성했으며, 2.4 버전의 변경 사항은 Kalle Svensson이 구현했습니다.
PEP 289: 제너레이터 표현식 (Generator Expressions)¶
Python 2.2에서 도입된 이터레이터 기능과 itertools 모듈은 전체 데이터 세트를 메모리에 유지할 필요 없이 대규모 데이터 세트를 순회하는 프로그램을 작성하기 쉽게 만듭니다. 리스트 컴프리헨션은 모든 항목을 포함하는 Python 리스트 객체를 생성하기 때문에 이러한 상황에 잘 맞지 않습니다. 이것은 불가피하게 모든 객체를 메모리로 가져오게 되어 데이터 세트가 매우 클 경우 문제가 될 수 있습니다. 기능적으로 스타일화된 프로그램을 작성하려고 할 때, 다음과 같은 코드를 작성하는 것이 자연스러울 것입니다:
links = [link for link in get_all_links() if not link.followed]
for link in links:
...
~ 대신에
for link in get_all_links():
if link.followed:
continue
...
첫 번째 방식이 더 간결하고 아마도 읽기 쉬우나, 연결 객체가 많은 경우 모든 연결 객체를 메모리에 한 번에 올리는 것을 방지하기 위해 두 번째 방식을 사용해야 합니다. 비교해 보십시오:
제너레이터 표현식은 리스트 컴프리헨션과 유사하게 작동하지만 전체 리스트를 실체화하지 않고, 대신 요소를 하나씩 반환하는 제너레이터를 생성합니다. 위 예시처럼 작성할 수 있습니다:
links = (link for link in get_all_links() if not link.followed)
for link in links:
...
제너레이터 표현식은 항상 괄호 안에 작성해야 하며, 상기 예시가 그렇습니다. 함수 호출을 알리는 괄호도 포함되므로, 함수에 즉시 전달할 이터레이터를 만들고 싶다면 다음과 같이 작성할 수 있습니다:
print sum(obj.count for obj in list_all_objects())
제너레이터 표현식은 리스트 컴프리헨션과 여러 면에서 작게 다릅니다. 가장 주목할 부분은 루프 변수(obj 가 위 예시임)는 제너레이터 표현식 외부에서는 접근할 수 없다는 것입니다. 리스트 컴프리헨션은 변수를 마지막 값으로 남기지만, 파이썬의 미래 버전에서는 이 부분이 변경되어 이 두 가지를 일치시킬 예정입니다.
더 보기
- PEP 289 - 제너레이터 표현식
Raymond Hettinger가 제안하고 Jiwon Seo가 구현했으며, Hye-Shik Chang의 초기 노력에 의해 주도되었습니다.
PEP 292: 더 간단한 문자열 치환¶
표준 라이브러리의 일부 새 클래스는 문자열에 변수를 치환하는 대안적인 메커니즘을 제공하며, 이러한 방식의 치환은 템플릿을 수정해야 하는 비전문 사용자에게 더 좋을 수 있습니다.
변수를 이름으로 치환하는 일반적인 방법은 % 연산자입니다:
>>> '%(page)i: %(title)s' % {'page':2, 'title': 'The Best of Times'}
'2: The Best of Times'
템플릿 문자열을 작성할 때 닫는 괄호 뒤에 i 나 s 를 잊어버리기 쉽습니다. 템플릿이 파이썬 모듈 내에 있는 경우 큰 문제가 아닌데, 코드를 실행하면 “Unsupported format character” ValueError 가 발생하고 문제를 수정하면 됩니다. 하지만 Mailman과 같이 사용자들에 의해 템플릿 문자열이나 번역이 편집되는 애플리케이션을 고려해 보세요. 이들에게 형식 문자열의 문법은 설명하기 복잡하며, 실수할 경우 도움 되는 피드백을 제공하기 어려울 수 있습니다.
PEP 292는 $ 를 사용하여 치환을 나타내는 Template 클래스를 string 모듈에 추가합니다:
>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'The Best of Times'})
'2: The Best of Times'
사전에 키가 누락된 경우, substitute() 메서드는 KeyError`를 발생시킵니다. 또한 누락된 키를 무시하는 :meth:`safe_substitute 메서드도 있습니다:
>>> t = string.Template('$page: $title')
>>> t.safe_substitute({'page':3})
'3: $title'
더 보기
- PEP 292 - 더 간단한 문자열 치환
Barry Warsaw가 작성하고 구현했습니다.
PEP 318: 함수 및 메서드용 데코레이터¶
Python 2.2는 정적 메서드와 클래스 메서드를 추가하여 Python의 객체 모델을 확장했지만, 정적 또는 클래스 메서드를 정의하는 새로운 방식을 제공하기 위해 파이썬 문법 자체를 확장하지는 않았습니다. 대신, 평소처럼 def 구문을 작성하고, 그 결과를 staticmethod() 또는 classmethod() 함수에 전달하여 해당 함수가 새 타입의 메서드로 래핑되도록 해야 했습니다. 코드는 다음과 같은 형태였습니다:
class C:
@classmethod
def meth (cls):
...
meth = classmethod(meth) # Rebind name to wrapped-up class method
메서드가 매우 길 경우, 함수 본문 이후의 classmethod() 호출을 놓치거나 잊기 쉽습니다.
본래의 의도는 이러한 정의를 더 읽기 쉽게 만들기 위해 구문을 추가하는 것이었지만, 2.2 버전 출시 당시에는 좋은 문법이 분명하지 않았습니다. 오늘날에도 좋은 문법은 아직 명확하지 않지만 사용자들이 이 기능에 대한 쉬운 접근을 요구하고 있으며, 그 필요성을 충족하는 새로운 구문 기능이 추가되었습니다.
새로운 기능의 이름은 “함수 데코레이터”입니다. 이 이름은 classmethod(), staticmethod() 등이 함수 객체에 추가적인 정보를 저장하는 아이디어에서 왔습니다. 즉, 디테일로 함수를 데코레이트(decorate) 하는 것입니다.
이 표기법은 Java로부터 가져온 것이며 '@' 문자를 표시자로 사용합니다. 새로운 구문을 사용하면 위 예시는 다음과 같이 작성됩니다:
class C:
@classmethod
def meth (cls):
...
@classmethod``는 ``meth=classmethod(meth) 할당의 약어입니다. 더 일반적으로, 다음을 가지고 있다면:
@A
@B
@C
def f ():
...
이는 다음과 같은 사전-데코레이터 코드와 동일합니다:
def f(): ...
f = A(B(C(f)))
데코레이터는 함수 정의보다 한 줄 이전에 배치되어야 하며, 라인마다 하나의 데코레이터를 사용해야 하고, def 문과 같은 줄에 배치할 수 없습니다. 즉, @A def f(): ... 방식은 허용되지 않습니다. 함수 정의만 데코레이션 할 수 있으며, 모듈 레벨 또는 클래스 내부에서 가능합니다. 클래스 정의는 데코레이션 할 수 없습니다.
데코레이터란 단순히 장식할 함수를 인자로 받아 동일한 함수 또는 새로운 객체 중 하나를 반환하는 함수입니다. 반환 값이 콜러블일 필요는 없지만 (보통은 그러합니다), 결과에 추가 데코레이터가 적용될 경우 예외입니다. 여러분만의 데코레이터를 쉽게 작성할 수 있습니다. 다음의 간단한 예시는 함수 객체에 속성을 설정합니다:
>>> def deco(func):
... func.attr = 'decorated'
... return func
...
>>> @deco
... def f(): pass
...
>>> f
<function f at 0x402ef0d4>
>>> f.attr
'decorated'
>>>
좀 더 실제적인 예시로서, 다음 데코레이터는 제공된 인자가 정수형인지 확인합니다:
def require_int (func):
def wrapper (arg):
assert isinstance(arg, int)
return func(arg)
return wrapper
@require_int
def p1 (arg):
print arg
@require_int
def p2(arg):
print arg*2
:pep:`318`에서 다음과 같은 아이디어를 더욱 개선한 버전을 포함하고 있습니다. 이 버전은 필요한 타입을 지정하고 반환되는 타입까지 확인할 수 있게 합니다.
데코레이터 함수는 인자를 받을 수 있습니다. 인자가 제공되면, 데코레이터 함수는 해당 인자들만 가지고 호출되어야 하며 새로운 데코레이터 함수를 반환해야 합니다. 이 함수는 단일 함수를 받고 함수를 반환해야 합니다. 즉, @A @B @C(args) 는 다음과 같이 작동합니다:
def f(): ...
_deco = C(args)
f = A(B(_deco(f)))
이것을 정확히 구현하는 것이 약간 머리를 아프게 느껴질 수 있지만, 그리 어렵지는 않습니다.
작은 수정사항으로 함수에 :attr:`func_name <function.__name__> 속성을 쓰기 가능하게 합니다. 이 속성은 트레이스백에서 함수 이름을 표시하는 데 사용되므로, 데코레이터는 구성되고 반환되는 모든 새 함수의 이름도 변경해야 합니다.
더 보기
- PEP 318 - 함수, 메서드 및 클래스를 위한 데코레이터
작성: Kevin D. Smith, Jim Jewett, 그리고 Skip Montanaro. 여러 사람이 함수 데코레이터를 구현하는 패치를 작성했지만, 실제로 포함된 것은 Mark Russell이 작성한 패치 #979728입니다.
- https://wiki.python.org/moin/PythonDecoratorLibrary
이 Wiki 페이지에는 데코레이터의 여러 예시가 포함되어 있습니다.
PEP 322: 역순 이터레이션¶
새 내장 함수인 reversed(seq) 는 시퀀스를 받아 해당 시퀀스의 요소를 역순으로 반복하는 이터레이터를 반환합니다.
>>> for i in reversed(xrange(1,4)):
... print i
...
3
2
1
range(1,4)[::-1]`와 같은 확장 슬라이싱과 비교했을 때, :func:`reversed` 는 읽기 쉬우며 더 빠르게 실행되고 훨씬 적은 메모리를 사용합니다.
reversed`() 가 임의의 이터레이터가 아닌 시퀀스만 받는지 유의하십시오. 이터레이터를 역순으로 바꾸고 싶다면, 먼저 :func:`list`를 사용해 리스트로 변환해야 합니다:
>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
... print line
...
root:*:0:0:System Administrator:/var/root:/bin/tcsh
...
더 보기
- PEP 322 - 역순 이터레이션
Raymond Hettinger가 작성하고 구현했습니다.
PEP 324: 새로운 subprocess 모듈¶
표준 라이브러리는 서브 프로세스를 실행하는 여러 가지 방법을 제공하며, 각 방법은 다른 기능과 복잡성 수준을 가집니다. os.system(command) 는 사용하기 쉽지만 느리고 (쉘 프로세스를 실행하여 명령어를 실행함), 위험합니다 (쉘의 메타 문자를 이스케이프하는 데 주의를 기울여야 합니다). popen2 모듈은 서브 프로세스로부터 표준 출력 및 표준 오류를 캡처할 수 있는 클래스를 제공하지만, 명명 규칙이 혼란스럽습니다. subprocess 모듈은 이를 정리하여 필요한 모든 기능을 제공하는 통합 인터페이스를 제공합니다.
:mod:`!popen2`의 여러 클래스 집합 대신, :mod:`subprocess`에는 :class:`subprocess.Popen`이라는 단일 클래스가 포함되어 있으며, 이 생성자는 여러 가지 다른 키워드 인자를 지원합니다:
class Popen(args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0):
args 는 일반적으로 서브 프로세스로 실행될 프로그램의 인자들인 문자열 시퀀스입니다. (shell 인수가 True인 경우, args 는 단일 문자열이 될 수 있으며 이는 os.system() 과 마찬가지로 쉘에 해석을 위해 전달됩니다.)
stdin, stdout, 및 stderr 은 서브 프로세스의 입력, 출력, 오류 스트림이 무엇인지 지정합니다. 파일 객체나 파일 디스크립터를 제공할 수 있고, 또는 상수 subprocess.PIPE 를 사용하여 서브 프로세스와 부모 사이에 파이프를 생성할 수도 있습니다.
생성자는 여러 가지 유용한 옵션을 가지고 있습니다:
close_fds 는 서브 프로세스를 실행하기 전에 모든 파일 디스크립터를 닫도록 요청합니다.
cwd 는 서브 프로세스가 실행될 작업 디렉터리를 지정합니다 (기본값은 부모의 작업 디렉터리입니다).
env 는 환경 변수를 지정하는 딕셔너리입니다.
preexec_fn 은 자식이 시작되기 전에 호출되는 함수입니다.
universal_newlines opens the child’s input and output using Python’s universal newlines feature.
Once you’ve created the Popen instance, you can call its wait()
method to pause until the subprocess has exited, poll() to check if it’s
exited without pausing, or communicate(data) to send the string data
to the subprocess’s standard input. communicate(data) then reads any
data that the subprocess has sent to its standard output or standard error,
returning a tuple (stdout_data, stderr_data).
call`은 인자를 :class:`Popen() 생성자에 전달하고 명령이 완료될 때까지 기다리며 서브 프로세스의 상태 코드를 반환하는 단축 함수입니다. 이는 안전한 대안으로서 os.system():: 역할을 할 수 있습니다.
sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
# 성공
...
else:
# dpkg이 오류를 반환함
...
명령은 셸을 사용하지 않고 호출됩니다. 정말로 셸을 사용하고 싶다면, shell=True 키워드 인자를 추가하고 시퀀스 대신 문자열을 제공할 수 있습니다:
sts = subprocess.call('dpkg -i /tmp/new-package.deb', shell=True)
이 PEP는 셸과 파이썬 코드의 다양한 예시를 가져와 :mod:`subprocess`를 사용하는 파이썬 코드로 어떻게 번역되는지 보여줍니다. 이 섹션의 내용을 읽어보시는 것을 강력히 권장합니다.
더 보기
- PEP 324 - subprocess - 새로운 프로세스 모듈
Peter Åstrand가 작성 및 구현했으며, Fredrik Lundh와 다른 사람들의 도움을 받았습니다.
PEP 327: Decimal Data Type¶
Python은 항상 기본 C double 타입을 기반으로 부동 소수점(FP) 숫자를 데이터 타입으로 지원해 왔습니다. 하지만 대부분의 프로그래밍 언어에서 부동 소수점 타입을 제공함에도 불구하고, 많은 사람들(심지어 프로그래머들도)이 부동 소수점 숫자가 특정 십진 분수를 정확하게 표현하지 못한다는 사실을 알지 못합니다. 새로운 Decimal 타입은 사용자가 지정한 정밀도 한계까지 이러한 분수를 정확하게 나타낼 수 있습니다.
십진수가 필요한 이유?¶
제한은 부동 소수점 숫자에 사용되는 표현에서 발생합니다. FP 숫자는 세 가지 구성 요소로 이루어져 있습니다:
부호는 양수일 수도, 음수일 수도 있습니다.
가수는 단일 자리 이진 숫자 뒤에 분수 부분이 오는 것입니다. 예를 들어, 2진수 표기법으로
1.01``은 ``1 + 0/2 + 1/4또는 십진수로 $1.25$와 같습니다.지수는 표현된 숫자에서 소수점이 어디에 위치하는지를 알려줍니다.
예를 들어, 숫자 $1.25$는 양수 부호, 1.01의 가수 값(이진수), 그리고 지수 0을 가집니다 (소수점을 이동할 필요가 없습니다). 숫자 5는 같은 부호와 가수를 가지지만, 가수가 4배로 곱해지기 때문에(지수 $2$의 거듭제곱으로 인해) 지수는 2입니다. $1.25 times 4$는 5와 같습니다.
현대 시스템은 보통 IEEE 754라는 표준을 준수하는 부동 소수점 지원을 제공합니다. C의 double 타입은 일반적으로 $64$비트 IEEE 754 숫자로 구현되며, 가수에 $52$비트 공간을 사용합니다. 이는 숫자를 $52$비트 정밀도로만 지정할 수 있음을 의미합니다. 만약 끝없이 반복되는 전개를 가진 숫자를 나타내려고 한다면, 그 전개는 $52$비트 이후에서 잘립니다. 불행하게도 대부분의 소프트웨어는 출력물을 십진수로 생성해야 하며, 십진수 기반의 일반적인 분수는 종종 이진수에서 순환 소수가 됩니다. 예를 들어, $1.1_ {10}$은 이진수 $1.0001100110011$... 이고 $.1_ {10}$는 $1/16 + 1/32 + 1/256$에 무한히 많은 추가 항을 더한 것입니다. IEEE 754는 이 무한히 반복되는 소수점들을 $52$자리 이후에서 잘라내야 하므로, 표현이 약간 부정확합니다.
숫자가 인쇄될 때 이러한 부정확성을 가끔 볼 수 있습니다:
>>> 1.1
1.1000000000000001
수치 출력 시 정확도가 항상 눈에 보이는 것은 아닙니다. 왜냐하면 부동소수점(FP) 대 십진 문자열 변환이 C 라이브러리에 의해 제공되며, 대부분의 C 라이브러리는 합리적인 출력을 생성하려고 노력하기 때문입니다. 하지만 표시되지 않더라도 부정확성은 여전히 존재하며, 후속 연산에서 오류가 증폭될 수 있습니다.
대부분의 응용 프로그램에서는 사소한 문제입니다. 제가 점을 플롯하고 모니터에 표시할 때, 1.1과 1.1000000000000001 사이의 차이는 눈에 보이지 않을 만큼 작습니다. 보고서는 종종 출력을 특정 소수점 자릿수로 제한하며, 숫자를 두 자리 또는 세 자리, 심지어 여덟 자리까지 반올림하더라도 오류는 결코 명확하게 나타나지 않습니다. 하지만 정말로 중요한 응용 프로그램의 경우, 자체 사용자 정의 산술 루틴을 구현하는 것이 많은 작업이 필요합니다.
이에 Decimal 타입이 생성되었습니다.
Decimal 타입¶
새로운 모듈인 decimal`가 파이썬 표준 라이브러리에 추가되었습니다. 여기에는 두 개의 클래스, 즉 :class:`Decimal`과 :class:`Context`가 포함되어 있습니다. :class:`Decimal 인스턴스는 숫자를 나타내고, Context 인스턴스는 정밀도 및 기본 반올림 모드와 같은 다양한 설정을 묶어 사용하는 데 사용됩니다.
Decimal 인스턴스는 일반적인 파이썬 정수나 FP 숫자와 마찬가지로 불변입니다. 생성된 후에는 인스턴스가 나타내는 값을 변경할 수 없습니다. Decimal 인스턴스는 정수 또는 문자열에서 생성할 수 있습니다:
>>> import decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")
또한 부호, 십진 자릿수의 튜플로 표현된 가수(mantissa), 지수를 포함하는 튜플을 제공할 수도 있습니다:
>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14.75")
주의 사항: 부호 비트(sign bit)는 부울 값이며, 따라서 0은 양수이고 1은 음수입니다.
부동소수점에서 변환하는 것은 약간의 문제가 있습니다: 1.1을 나타내는 FP 숫자가 정확히 1.1에 해당하는 십진수가 되어야 할지, 아니면 추가된 부정확성 값(whatever inaccuracies are introduced)까지 더한 값을 기반으로 해야 할까요? 결정을 내린 결과, 이 문제를 회피하기로 하고 이러한 변환은 API에서 제외했습니다. 대신 원하는 정밀도를 사용하여 부동소수점을 문자열로 변환한 다음 해당 문자열을 Decimal 생성자에 전달해야 합니다:
>>> f = 1.1
>>> decimal.Decimal(str(f))
Decimal("1.1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1.100000000000")
Decimal 인스턴스를 갖게 되면, 일반적인 수학 연산을 수행할 수 있습니다. 한 가지 제한 사항이 있는데, 거듭제곱은 정수 지수가 필요합니다:
>>> a = decimal.Decimal('35.72')
>>> b = decimal.Decimal('1.73')
>>> a+b
Decimal("37.45")
>>> a-b
Decimal("33.99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a ** 2
Decimal("1275.9184")
>>> a**b
Traceback (most recent call last):
...
decimal.InvalidOperation: x ** (non-integer)
Decimal 인스턴스를 정수와 결합할 수는 있지만, 부동소수점 숫자와는 할 수 없습니다:
>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (most recent call last):
...
TypeError: You can interact Decimal only with int, long or Decimal data types.
>>>
Decimal 숫자는 math 및 cmath 모듈에서 사용할 수 있지만, 연산이 수행되기 전에 부동소수점 숫자로 즉시 변환된다는 점에 유의하여, 정밀도와 정확도의 손실 가능성이 있을 수 있습니다. 또한 :class:`Decimal`이 아닌 일반적인 부동소수점 숫자를 반환받게 됩니다.
>>> import math, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> math.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j
Decimal 인스턴스는 sqrt() 메서드를 가지고 있어 :class:`Decimal`을 반환하지만, 삼각 함수와 같은 다른 것이 필요한 경우 직접 구현해야 합니다.
>>> d.sqrt()
Decimal("351364.1828820134592177245001")
Context 타입¶
Context 클래스의 인스턴스는 십진 연산을 위한 여러 설정을 캡슐화합니다:
:attr:`prec`은 정밀도, 즉 소수점 자릿수를 나타냅니다.
rounding`은 반올림 모드를 지정합니다. :mod:`decimal모듈에는 다양한 가능성을 위한 상수들이 있습니다:ROUND_DOWN,ROUND_CEILING,ROUND_HALF_EVEN, 그리고 그 외 여러 가지가 있습니다.:attr:`traps`는 특정 오류 조건 발생 시 무엇이 발생하는지 지정하는 딕셔너리입니다. 즉, 예외가 발생하거나 값이 반환됩니다. 오류 조건의 몇 가지 예로는 0으로 나누기, 정밀도 손실 및 오버플로가 있습니다.
:func:`getcontext`를 호출하여 스레드별 기본 컨텍스트를 사용할 수 있으며, 이 커텍스트의 속성을 변경하여 기본 정밀도, 반올림 또는 트랩 처리를 수정할 수 있습니다. 다음 예제는 기본 컨텍스트의 정밀도를 변경했을 때의 영향을 보여줍니다:
>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0.142857143")
오류 조건에 대한 기본 조치는 선택 가능하며; 이 모듈은 무한대나 숫자가 아님(not-a-number)과 같은 특수 값을 반환하거나, 예외를 발생시킬 수 있습니다:
>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (most recent call last):
...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinity")
>>>
Context 인스턴스는 또한 to_eng_string() 및 :meth:`to_sci_string`과 같이 숫자를 포맷팅하는 다양한 메서드를 가지고 있습니다.
더 자세한 내용은 빠른 시작 튜토리얼과 참고 자료가 포함된 decimal 모듈의 문서를 참조하십시오.
더 보기
- PEP 327: 십진 데이터 유형
Facundo Batista가 작성하고 Facundo Batista, Eric Price, Raymond Hettinger, Aahz, Tim Peters에 의해 구현되었습니다.
- <https://web.archive.org/web/20230604072523/http://www.lahey.com/float.htm>
http://www.lahey.com/float.htm__ 이 기사는 부동 소수점 부정확성이 야기할 수 있는 여러 문제점을 설명하기 위해 포트란(Fortran) 코드를 사용합니다.
- https://speleotrove.com/decimal/
십진 기반 표현 방식에 대한 설명입니다. 이 표현 방식은 표준으로 제안되고 있으며, 새로운 Python decimal 유형의 기본 원리가 됩니다. 이 자료는 Rexx 언어 설계자인 Mike Cowlishaw가 작성한 부분이 많습니다.
PEP 328: 다중 줄 임포트¶
한 언어 변경 사항은 모듈에서 많은 이름을 가져오기 쉽게 만드는 것을 목표로 한 작은 구문상의 수정입니다. from module import names 문에서, names 는 쉼표로 구분된 이름의 시퀀스입니다. 이 시퀀스가 매우 길 경우, 동일 모듈에서 여러 번 임포트를 하거나 다음과 같이 역슬래시(``)를 사용하여 줄바꿈을 이스케이프할 수 있습니다:
from SimpleXMLRPCServer import SimpleXMLRPCServer,\
SimpleXMLRPCRequestHandler,\
CGIXMLRPCRequestHandler,\
resolve_dotted_attribute
파이썬 2.4에서의 구문상 변경은 단순히 이름들을 괄호 안에 넣는 것을 허용하는 것입니다. 파이썬은 괄호로 묶인 표현식 내부의 줄바꿈을 무시하므로, 더 이상 역슬래시가 필요하지 않습니다:
from SimpleXMLRPCServer import (SimpleXMLRPCServer,
SimpleXMLRPCRequestHandler,
CGIXMLRPCRequestHandler,
resolve_dotted_attribute)
PEP는 또한 모든 import 문이 절대 임포트이며, 상대 임포트를 나타내는 선행 . 문자를 포함해야 한다고 제안합니다. 이 PEP의 부분은 Python 2.4용으로 구현되지 않았으나, Python 2.5에서 완료되었습니다.
더 보기
- PEP 328 - 임포트: 복수 줄 및 절대/상대
Aahz가 작성했습니다. 다중 줄 임포트는 Dima Dorfman이 구현했습니다.
PEP 331: 로케일 독립적 부동 소수점/문자열 변환¶
locale 모듈은 파이썬 소프트웨어가 특정 국가 또는 언어에 맞춰 지역화된 다양한 변환 및 표시 규칙을 선택할 수 있게 합니다. 그러나 이 모듈은 숫자 로케일을 변경하지 않도록 주의를 기울였는데, 이는 파이썬 구현의 여러 함수가 숫자 로케일이 'C' 로케일에 유지되기를 요구했기 때문입니다. 종종 코드가 C 라이브러리의 atof() 함수를 사용했기 때문에 ऐसा였습니다.
숫자 로케일을 설정하지 않은 것은 문제가 되었는데, 이는 서드파티 C 라이브러리를 사용하는 확장 프로그램들이 올바른 로케일 설정을 갖지 못했기 때문입니다. 동기를 부여한 예시는 사용자 인터페이스 위젯이 현재 로케일로 숫자를 표시하지 않았던 GTK+였습니다.
PEP에서 설명하는 해결책은 세 가지 새 함수를 Python API에 추가하여, 지역화 설정에 구애받지 않는 ASCII 전용 변환을 수행하는 것입니다:
PyOS_ascii_strtod(str, ptr)``와 ``PyOS_ascii_atof(str, ptr)모두 문자열을 C :c:expr:`double`로 변환합니다.PyOS_ascii_formatd(buffer, buf_len, format, d)는 double 을 ASCII 문자열로 변환합니다.
이 함수들의 코드는 GLib 라이브러리(https://developer-old.gnome.org/glib/2.26/)에서 가져왔으며, 개발자들이 관련 함수들을 너그러이 라이선스 변경하여 Python 소프트웨어 재단에 기증했습니다. 이제 locale 모듈은 숫자 로케일을 변경할 수 있게 되어 GTK+와 같은 확장이 올바른 결과를 생성하도록 할 수 있습니다.
더 보기
- PEP 331: 로케일 독립적 부동 소수점/문자열 변환
Christian R. Reis가 작성하고 Gustavo Carneiro가 구현했습니다.
다른 언어 변경 사항¶
다음은 Python 2.4가 핵심 파이썬 언어에 적용하는 모든 변경 사항입니다:
함수와 메서드 데코레이터가 추가되었습니다 (PEP 318).
내장된
set`과 :func:`frozenset()타입이 추가되었습니다 (PEP 218). 다른 새로운 내장 기능으로는reversed(seq)함수 (PEP 322)가 있습니다.제너레이터 표현식이 추가되었습니다 (PEP 289).
특정 숫자 표현식은 더 이상 32비트 또는 64비트로 제한된 값을 반환하지 않습니다 (PEP 237).
이제
from module import names문에서 이름들의 목록을 괄호로 감쌀 수 있습니다 (PEP 328).update()메서드는 이제dict생성자가 받아들이는 것과 동일한 인자 형식을 허용합니다. 여기에는 모든 매핑, 모든 키/값 쌍의 이터러블, 그리고 키워드 인자(‘keyword arguments’)가 포함됩니다. (Raymond Hettinger 기여.)문자열 메서드
ljust(),rjust(), 및 :meth:`center`는 이제 공백이 아닌 채우기 문자(fill character)를 지정할 수 있는 선택적 인자를 받습니다. (Raymond Hettinger 기여.)Strings also gained an
rsplit()method that works like thesplit()method but splits from the end of the string. (Contributed by Sean Reifschneider.)>>> 'www.python.org'.split('.', 1) ['www', 'python.org'] 'www.python.org'.rsplit('.', 1) ['www.python', 'org']
리스트의
sort()메서드에 cmp, key, 및 reverse 세 개의 키워드 매개변수가 추가되었습니다. 이 매개변수들은 :meth:`sort`의 일반적인 사용 사례 중 일부를 간소화합니다. 이 모든 매개변수는 선택 사항입니다.cmp 매개변수용 값은 두 개의 매개변수를 받아들이고, 매개변수가 비교되는 방식에 따라 -1, 0, 또는 +1을 반환하는 비교 함수여야 합니다. 이 함수는 리스트를 정렬하는 데 사용됩니다. 이전에는 이것이 :meth:`sort`에 제공할 수 있는 유일한 매개변수였습니다.
key 는 리스트 요소를 받아서 요소에 대한 비교 키를 반환하는 단일 매개변수 함수여야 합니다. 그런 다음 리스트는 이 비교 키들을 사용하여 정렬됩니다. 다음 예제는 리스트를 대소문자 구분 없이 정렬합니다:
>>> L = ['A', 'b', 'c', 'D'] >>> L.sort() # 대소문자 구분 정렬 >>> L ['A', 'D', 'b', 'c'] >>> # 키 매개변수를 사용하여 리스트 정렬하기 >>> L.sort(key=lambda x: x.lower()) >>> L ['A', 'b', 'c', 'D'] >>> # 구식 방식 >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower())) >>> L ['A', 'b', 'c', 'D']
cmp 매개변수를 사용하는 마지막 예제는 대소문자 구분 없이 정렬하는 옛 방식입니다. 작동은 하지만 key 매개변수를 사용하는 것보다 느립니다. key 를 사용하면 리스트의 각 요소에 대해
lower()메서드를 한 번만 호출하는 반면, cmp 를 사용하면 각 비교마다 두 번씩 호출하므로, key 를 사용하는 것이lower()메서드 호출 횟수를 절약해 줍니다.간단한 키 함수 및 비교 함수의 경우, 바인딩되지 않은 메서드를 사용함으로써
lambda표현식을 피할 수 있는 경우가 많습니다. 예를 들어, 위와 같은 대소문자 구분 없는 정렬은 다음과 같이 작성하는 것이 가장 좋습니다:>>> L.sort(key=str.lower) >>> L ['A', 'b', 'c', 'D']
마지막으로, reverse 매개변수는 논리값(Boolean value)을 받습니다. 값이 true인 경우, 리스트는 역순으로 정렬됩니다.
L.sort(); L.reverse()대신 이제L.sort(reverse=True)를 작성할 수 있습니다.정렬 결과가 안정적임이 보장됩니다. 이는 같은 키를 가진 두 항목이 입력되었던 순서와 동일한 순서로 반환된다는 것을 의미합니다. 예를 들어, 사람들의 리스트를 이름으로 정렬한 다음 나이로 다시 정렬하면, 같은 나이를 가진 사람들이 이름순으로 정렬된, 나이순으로 정렬된 리스트가 생성됩니다.
(All changes to
sort()contributed by Raymond Hettinger.)표현식에서 사용할 수 있지만, 제자리(in-place)
list.sort()메서드와 유사하게 작동하는 새로운 내장 함수sorted(iterable)가 추가되었습니다. 차이점은 다음과 같습니다:입력은 모든 이터러블일 수 있습니다;
새롭게 형성된 복사본이 정렬되어 원본을 그대로 유지합니다; 그리고
표현식은 새로운 정렬된 복사본을 반환합니다.
>>> L = [9,7,8,3,2,4,1,6,5] >>> [10+i for i in sorted(L)] # 리스트 컴프리헨션에서 사용 가능 [11, 12, 13, 14, 15, 16, 17, 18, 19] >>> L # 원본은 변경되지 않습니다 [9,7,8,3,2,4,1,6,5] >>> sorted('Monty Python') # 모든 이터러블이 입력될 수 있음 [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y'] >>> # 키 값으로 정렬된 dict의 내용 목록 보기 >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5) >>> for k, v in sorted(colormap.iteritems()): ... print k, v ... black 4 blue 2 green 3 red 1 yellow 5
(Raymond Hettinger 작성.)
정수 연산은 더 이상
OverflowWarning`을 발생시키지 않습니다. :exc:`OverflowWarning경고는 Python 2.5에서 사라집니다.인터프리터에 이름(name)을 받아서, 해당 모듈을
sys.path에서 검색하고 스크립트로 실행하는 새로운 스위치-m이 생겼습니다. 예를 들어, 이제python -m profile로 Python 프로파일러를 실행할 수 있습니다. (Nick Coghlan 기여.)eval(expr, globals, locals)및execfile(filename, globals, locals)함수와 exec 문은 이제 locals 매개변수에 임의의 매핑 타입을 허용합니다. 이전에는 정규 Python 딕셔너리여야 했습니다. (Raymond Hettinger 작성.)zip()빌트인 함수와itertools.izip`은 이제 인자 없이 호출할 경우 빈 리스트를 반환합니다. 이전에는 :exc:`TypeError()예외를 발생시켰습니다. 이는 변수 길이 인자 목록을 사용하는 데 더 적합하게 만듭니다:>>> def transpose(array): ... return zip(*array) ... >>> transpose([(1,2,3), (4,5,6)]) [(1, 4), (2, 5), (3, 6)] >>> transpose([]) []
(Raymond Hettinger 작성.)
모듈 가져오기 실패가 더 이상
sys.modules에 부분 초기화된 모듈 객체를 남기지 않습니다. 남아 있던 불완전한 모듈 객체는 다음 import 작업에서 같은 모듈을 가져올 때 혼란을 주어, 이해하기 어려운 오류를 초래했습니다. (Tim Peters 수정.)Noneis now a constant; code that binds a new value to the nameNoneis now a syntax error. (Contributed by Raymond Hettinger.)
최적화들`¶
리스트 및 튜플 슬라이싱에 대한 내부 루프가 최적화되어 이제 약 3분의 1 더 빠르게 실행됩니다. 또한 딕셔너리에 대한 내부 루프도 최적화되어
keys(),values(),items(),iterkeys(),itervalues(), 및 :meth:`iteritems`의 성능 향상이 이루어졌습니다. (Raymond Hettinger 기여.)리스트를 늘리고 줄이는 메커니즘이 속도와 공간 효율성을 위해 최적화되었습니다. 리스트에서 추가 및 제거하는 작업은 더 효율적인 코드 경로와 기본 시스템
realloc()사용 감소로 인해 이제 더 빠르게 실행됩니다. 리스트 컴프리헨션도 혜택을 받습니다. 또한 :meth:`list.extend`도 최적화되어 확장하기 전에 인자를 임시 리스트로 변환하는 과정이 없습니다. (Raymond Hettinger 작성.)list(),tuple(),map(),filter(), 및zip`은 이제 :meth:`__len__()메서드를 제공하는 순서가 아닌 인자와 함께 몇 배 더 빠르게 실행됩니다. (Raymond Hettinger 작성.)메서드
list.__getitem__(),dict.__getitem__(), 및dict.__contains__`는 이제 :class:`wrapper_descriptor()객체 대신method_descriptor객체로 구현됩니다. 이러한 접근 형태를 사용하면 성능이 두 배가 되고, 함수형의 인자로 사용하는 데 더 적합해집니다:map(mydict.__getitem__, keylist)(Raymond Hettinger 작성.)새로운 opcode인
LIST_APPEND가 추가되어 리스트 컴프리헨션의 생성된 바이트코드를 단순화하고 속도를 약 3분의 1까지 향상시켰습니다. (Raymond Hettinger 작성.)peephole 바이트코드 최적화기가 더 짧고 빠른 바이트코드를 생성하도록 개선되어, 놀라울 정도로 결과적인 바이트코드는 가독성이 높아졌습니다. (Raymond Hettinger 개선.)
문장
s = s + "abc"및s += "abc"의 문자열 연결은 특정 상황에서 더 효율적으로 수행됩니다. 이 최적화는 Jython과 같은 다른 Python 구현체에서는 존재하지 않을 수 있으므로, 이에 의존해서는 안 됩니다. 많은 문자열을 효율적으로 붙이고 싶을 때는 여전히 strings의join()메서드를 사용하는 것이 권장됩니다. (Armin Rigo 작성.)
2.4 최적화의 순 효과는 Python 2.4가 pystone 벤치마크를 실행할 때 Python 2.3보다 약 5% 더 빠르고, Python 2.2보다 35% 더 빠른 것을 의미합니다. (pystone은 특히 좋은 벤치마크는 아니지만, Python 성능을 측정하는 가장 일반적으로 사용되는 측정 방법입니다. 사용자 자신의 애플리케이션은 Python 2.4로부터 더 크거나 작은 이점을 보일 수 있습니다.)
새롭고, 개선되고, 사용 중단된 모듈¶
예상대로 Python 표준 라이브러리에 여러 가지 향상 및 버그 수정 사항들이 적용되었습니다. 여기에는 모듈 이름에 따라 알파벳순으로 정렬된 가장 주목할 만한 변경 사항들의 일부 목록이 있습니다. 더 완전한 변경 목록은 소스 트리 내의 :file:`Misc/NEWS` 파일을 참조하거나 모든 세부 정보를 보려면 CVS 로그를 확인하십시오.
asyncore모듈의loop()함수에는 요청한 횟수만큼 폴링 루프를 통과할 수 있도록 하는 count 매개변수가 추가되었습니다. 기본값은 여전히 영원히 루프하는 것입니다.base64모듈은 이제 Base64, Base32 및 Base16 인코딩 및 디코딩에 대한 더욱 완벽한 RFC 3548 지원을 갖추었으며, 선택적 케이스 폴딩과 선택적 대체 알파벳이 포함됩니다. (Barry Warsaw 기여.)bisect모듈은 이제 성능 향상을 위해 근본적인 C 구현을 갖추었습니다. (Dmitry Vasiliev 기여.)Hye-Shik Chang이 유지 관리하는 동아시아 코덱 모음인 CJKCodecs가 2.4에 통합되었습니다. 새로운 인코딩은 다음과 같습니다:
중국어(PRC): gb2312, gbk, gb18030, big5hkscs, hz
중국어(ROC): big5, cp950
- 일본어: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,
iso-2022-jp-1, iso-2022-jp-2, iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004, shift-jis, shift-jisx0213, shift-jis-2004
한국어: cp949, euc-kr, johab, iso-2022-kr
기타 새로운 인코딩이 추가되었습니다: HP Roman8, ISO_8859-11, ISO_8859-16, PCTP-154, 및 TIS-620.
UTF-8 및 UTF-16 코덱이 이제 부분적인 입력 수신에 대해 더 잘 처리합니다. 이전에는
StreamReader클래스가 더 많은 데이터를 읽으려고 시도하여 스트림에서 디코딩을 재개하는 것이 불가능했습니다.read()메서드는 이제 가능한 모든 데이터를 반환하며, 향후 호출은 이전 지점부터 계속 디코딩을 재개합니다. (Walter Dörwald 구현.)다양한 전문 컬렉션 데이터 타입을 위한 새로운
collections모듈이 있습니다. 현재는 단일 타입인, 양 끝에서 요소를 효율적으로 추가하고 제거할 수 있는 이중 끝 큐인 :class:`deque`를 포함하고 있습니다:>>> from collections import deque >>> d = deque('ghi') # 세 항목의 새 데크를 만듭니다 >>> d.append('j') # 오른쪽에 새 항목을 추가합니다 >>> d.appendleft('f') # 왼쪽에 새 항목을 추가합니다 >>> d # 데크의 표현을 보여줍니다 deque(['f', 'g', 'h', 'i', 'j']) >>> d.pop() # 가장 오른쪽 항목을 반환하고 제거합니다 'j' >>> d.popleft() # 가장 왼쪽 항목을 반환하고 제거합니다 'f' >>> list(d) # 데크 내용을 리스트로 변환합니다 ['g', 'h', 'i'] >>> 'h' in d # 데크에서 검색합니다 True
Queue및threading모듈과 같은 여러 모듈이 성능 향상을 위해 :class:`collections.deque`를 활용합니다. (Raymond Hettinger 기여.)ConfigParser클래스가 약간 개선되었습니다. 이제read()메서드는 성공적으로 구문 분석된 파일 리스트를 반환하며,set()메서드는 문자열이 아닌 value 인수를 전달한 경우 :exc:`TypeError`를 발생시킵니다. (John Belmonte 및 David Goodger 기여.)curses모듈은 이제 ncurses 확장 기능인 :func:`use_default_colors`를 지원합니다. 터미널이 투명도를 지원하는 플랫폼에서는 이를 통해 투명 배경을 사용할 수 있습니다. (Jörg Lehmann 기여.)difflib모듈은 이제 텍스트 두 버전을 나란히 비교하여 보여주는 HTML 테이블을 생성하는HtmlDiff클래스를 포함합니다. (Dan Gass 기여.)email패키지가 3.0 버전으로 업데이트되었으며, 이 과정에서 여러 사용되지 않는 API가 제거되고 Python 2.3 이전 버전의 지원이 제외되었습니다. 패키지의 3.0 버전은 MIME 메시지에 대해 새로운 증분 파서를 사용하며, 이는email.FeedParser모듈에서 사용할 수 있습니다. 새 파서는 전체 메시지를 메모리에 읽을 필요가 없으며, 메시지가 잘못된 경우 예외를 발생시키지 않고 대신 메시지의defect속성에 모든 문제를 기록합니다. (Anthony Baxter, Barry Warsaw, Thomas Wouters 등이 개발.)heapq모듈은 C로 변환되었습니다. 그 결과로 얻은 10배의 속도 개선 덕분에 이 모듈은 대용량 데이터 처리에 적합합니다. 게다가, 이 모듈에는nlargest()및 :func:`nsmallest`라는 두 가지 새로운 함수가 추가되어 전체 정렬 없이 힙을 사용하여 데이터 세트에서 N개의 가장 크거나 작은 값을 찾을 수 있습니다. (Raymond Hettinger 기여.)The
httplibmodule now contains constants for HTTP status codes defined in various HTTP-related RFC documents. Constants have names such asOK,CREATED,CONTINUE, andMOVED_PERMANENTLY; use pydoc to get a full list. (Contributed by Andrew Eland.)The
imaplibmodule now supports IMAP’s THREAD command (contributed by Yves Dionne) and newdeleteacl()andmyrights()methods (contributed by Arnaud Mazin).itertools모듈에groupby(iterable[, *func*])함수가 추가되었습니다. iterable 은 요소를 반복하여 스트림을 반환할 수 있는 것이며, 선택적 func 매개변수는 요소를 받아 키 값을 반환하는 함수입니다. func 를 생략하면 키는 단순히 요소 자체가 됩니다. 그러면groupby()는 요소를 일치하는 키 값을 가진 하위 시퀀스로 그룹화하고, 키 값과 해당 하위 시퀀스를 포함하는 이터레이터로 구성된 2-튜플 시리즈를 반환합니다.더 명확하게 이해할 수 있는 예시입니다. key 함수는 단순히 숫자가 짝수인지 홀수인지를 반환하므로, :func:`groupby`의 결과는 연속적인 홀수 또는 짝수의 실행을 반환하는 것입니다.
>>> import itertools >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14] >>> for key_val, it in itertools.groupby(L, lambda x: x % 2): ... print key_val, list(it) ... 0 [2, 4, 6] 1 [7] 0 [8] 1 [9, 11] 0 [12, 14] >>>
groupby`는 일반적으로 정렬된 입력과 함께 사용됩니다. :func:`groupby`의 논리는 유닉스의 ``uniq`()필터와 유사하여 중복 요소를 제거하거나, 개수를 세거나, 식별하는 데 유용합니다:>>> word = 'abracadabra' >>> letters = sorted(word) # 문자열을 정렬된 문자 리스트로 변환 >>> letters ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r'] >>> for k, g in itertools.groupby(letters): ... print k, list(g) ... a ['a', 'a', 'a', 'a', 'a'] b ['b', 'b'] c ['c'] d ['d'] r ['r', 'r'] >>> # 고유한 문자 목록 만들기 >>> [k for k, g in groupby(letters)] ['a', 'b', 'c', 'd', 'r'] >>> # 문자 발생 횟수 세기 >>> [(k, len(list(g))) for k, g in groupby(letters)] [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
(Hye-Shik Chang 기여.)
itertools에는 또한 iterator 를 복제하여 N 개의 독립적인 이터레이터를 반환하는tee(iterator, N)이라는 함수가 추가되었습니다. N 이 생략되면 기본값은 2입니다.>>> L = [1,2,3] >>> i1, i2 = itertools.tee(L) >>> i1,i2 (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>) >>> list(i1) # 첫 번째 이터레이터를 소진할 때까지 실행 [1, 2, 3] >>> list(i2) # 두 번째 이터레이터를 소진할 때까지 실행 [1, 2, 3]
:func:`tee`는 반환되는 값을 복사본으로 유지해야 한다는 점에 유의하십시오. 최악의 경우 모든 값을 유지해야 할 수도 있습니다. 따라서 선행 이터레이터가 긴 입력 스트림에서 후속 이터레이터보다 너무 많이 앞서 나갈 수 있는 경우에는 주의하여 사용해야 합니다. 분리가 큰 경우, :func:`list`를 사용하는 것이 더 낫습니다. 이터레이터들이 서로 가깝게 추적할 때는 :func:`tee`가 이상적입니다. 가능한 응용 프로그램에는 북마킹, 윈도잉 또는 전방 탐색 이터레이터 등이 있습니다. (Raymond Hettinger 기여.)
A number of functions were added to the
localemodule, such asbind_textdomain_codeset()to specify a particular encoding and a family ofl*gettext()functions that return messages in the chosen encoding. (Contributed by Gustavo Niemeyer.)Some keyword arguments were added to the
loggingpackage’sbasicConfig()function to simplify log configuration. The default behavior is to log messages to standard error, but various keyword arguments can be specified to log to a particular file, change the logging format, or set the logging level. For example:import logging logging.basicConfig(filename='/var/log/application.log', level=0, # 모든 메시지 로깅 format='%(levelname):%(process):%(thread):%(message)')
logging패키지에 추가된 다른 기능들로는log(level, msg)편의 메서드와 타이밍 간격으로 로그 파일을 순환하는TimedRotatingFileHandler클래스가 있습니다:: 모듈에는 이미 파일 크기가 특정 크기를 초과하면 로그를 순환하는 :class:`RotatingFileHandler`가 있었습니다. 두 클래스는 다른 로테이팅 핸들러를 구현하는 데 사용될 수 있는 새로운 :class:`BaseRotatingHandler`에서 파생됩니다.(Vinay Sajip에 의해 구현되었습니다.)
marshal모듈은 이제 데이터 구조를 언패킹할 때 내부 문자열을 공유합니다. 이는 특정 pickle 문자열의 크기를 줄일 수 있지만, 주요 효과는.pyc파일의 크기를 크게 줄이는 것입니다. (Martin von Löwis 기여.)nntplib모듈의NNTP클래스에 개별 그룹 또는 그룹 범위에 대한 뉴스그룹 설명을 검색하는description()및descriptions()메서드가 추가되었습니다. (Jürgen A. Erhard 기여.)operator모듈에 두 가지 새 함수인attrgetter(attr)와itemgetter(index)가 추가되었습니다. 이 두 함수는 단일 인수를 받아 해당 속성 또는 항목을 반환하는 콜러블을 반환하며, 이 콜러블들은map()이나sorted()와 함께 사용될 때 우수한 데이터 추출기가 됩니다. 예를 들면:>>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)] >>> map(operator.itemgetter(0), L) ['c', 'd', 'a', 'b'] >>> map(operator.itemgetter(1), L) [2, 1, 4, 3] >>> sorted(L, key=operator.itemgetter(1)) # 리스트를 두 번째 튜플 항목으로 정렬 [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
(Raymond Hettinger 작성.)
optparse모듈이 여러 방식으로 업데이트되었습니다. 이 모듈은 이제 자체 메시지를gettext.gettext`를 통해 전달함으로써 Optik의 도움말과 오류 메시지 현지화를 가능하게 합니다. 옵션에 대한 도움말 메시지에는 이제 `()’%default’`` 문자열을 포함할 수 있으며, 이는 해당 옵션의 기본값으로 대체됩니다. (Greg Ward 기여.)장기 계획은 향후 파이썬 릴리스에서
rfc822모듈을email패키지 방식으로 대체하는 것입니다. 이를 위해email.Utils.formatdate함수가 :func:`!rfc822.formatdate`의 교체품으로 사용될 수 있도록 변경되었습니다. 이 점을 염두에 두고 새로운 전자우편 처리 코드를 작성할 수도 있습니다. (Anthony Baxter 구현.)os모듈에 새urandom(n)함수가 추가되었으며, 이는 n 바이트의 무작위 데이터가 포함된 문자열을 반환합니다. 이 함수는 리눅스의 :file:`/dev/urandom`이나 Windows CryptoAPI와 같은 플랫폼별 난수 소스에 대한 액세스를 제공합니다. (Trevor Perrin 기여.)또 다른 새 함수:
os.path.lexists(path)``는 *path*로 지정된 파일이 심볼릭 링크인지 여부에 관계없이 존재하는지 여부를 true로 반환합니다. 이는 *path*가 존재하지 않는 목적지를 가리키는 심볼릭 링크인 경우 false를 반환하는 기존의 ``os.path.exists(path)함수와 다릅니다. (Beni Cherniavsky 기여.)os모듈의 기반이 되는posix모듈에 새로운getsid()함수가 추가되었습니다. (J. Raynor 기여.)poplib모듈은 이제 SSL을 통한 POP를 지원합니다. (Hector Urtubia 기여.)profile모듈에서 C 확장 기능을 프로파일링할 수 있게 되었습니다. (Nick Bastin 기여.)random모듈에는 N 비트 길이의 큰 정수를 반환하는getrandbits(N)이라는 새 메서드가 있습니다. 기존randrange()메서드는 적절한 경우getrandbits()를 사용하여 임의로 큰 난수 생성 효율성을 높였습니다. (Raymond Hettinger 기여.)re모듈에서 수락하는 정규 표현식 언어에(?(group)A|B)형태로 작성된 간단한 조건부 표현식이 확장되었습니다. group 은 숫자 그룹 ID이거나, 해당 표현식의 앞부분에서(?P<group>...)로 정의된 그룹 이름 중 하나입니다. 지정된 그룹과 일치하면 정규 표현식 패턴 A 를 문자열에 테스트하고; 그룹이 일치하지 않으면 대신 패턴 B 가 사용됩니다. (Gustavo Niemeyer 기여.)re모듈은 또한 Gustavo Niemeyer님의 대규모 작업 덕분에 더 이상 재귀적으로 작동하지 않습니다. 재귀 정규 표현식 엔진에서는 특정 패턴이 많은 양의 C 스택 공간을 소비하여, 스택 오버플로우가 발생할 수 있습니다. 예를 들어,a문자 30000바이트 문자열을 표현식(a|b)+에 매칭하면 문자당 하나의 스택 프레임이 소모되었습니다. Python 2.3은 스택 오버플로우를 확인하고RuntimeError예외를 발생시키려고 했지만, 특정 패턴이 이 검사를 우회할 수 있었고 운이 나쁘면 Python에서 segfault가 발생할 수도 있었습니다. Python 2.4의 정규 표현식 엔진은 문제가 없이 이 패턴을 매칭할 수 있습니다.signal모듈은 이제signal.signal()함수의 매개변수에 대해 더 엄격한 오류 검사를 수행합니다. 예를 들어,SIGKILL시그널에 핸들러를 설정할 수 없습니다. 이전 버전의 Python에서는 이를 조용히 받아들였지만, 2.4에서는RuntimeError예외가 발생합니다.socket모듈에 두 개의 새로운 함수가 추가되었습니다.socketpair()는 연결된 소켓 쌍을 반환하며,getservbyport(port)은 주어진 포트 번호의 서비스 이름을 찾습니다. (Dave Cole과 Barry Warsaw가 기여했습니다.)sys.exitfunc()함수는 지원 중단되었습니다. 코드는 기존atexit모듈을 사용해야 하며, 이 모듈은 여러 종료 함수의 호출을 올바르게 처리합니다. 궁극적으로 :func:`sys.exitfunc`는 :mod:`atexit`에 의해서만 접근되는 순전히 내부 인터페이스가 될 것입니다.tarfile모듈은 이제 기본적으로 GNU 형식의 tar 파일을 생성합니다. (Lars Gustäbel이 기여했습니다.)threading모듈은 이제 스레드별 데이터를 지원하는 우아하게 간단한 방법을 갖추게 되었습니다. 이 모듈에는 여러 스레드에 로컬인 속성 값을 가지는local클래스가 포함되어 있습니다:import threading data = threading.local() data.number = 42 data.url = ('www.python.org', 80)
다른 스레드는
number및url속성에 자체 값을 할당하고 검색할 수 있습니다. :class:`local`을 서브클래스화하여 속성을 초기화하거나 메서드를 추가할 수 있습니다. (Jim Fulton이 기여했습니다.)timeit모듈은 타이밍 루프 동안 주기적인 가비지 컬렉션을 이제 자동으로 비활성화합니다. 이 변경 사항으로 연속 측정 시간이 더 비교하기 쉬워졌습니다. (Raymond Hettinger가 기여했습니다.)weakref모듈은 이제 파이썬 함수, 클래스 인스턴스, 세트, frozenset, deques, 배열, 파일, 소켓 및 정규 표현식 패턴 객체를 포함하여 더 광범위한 종류의 객체를 지원합니다. (Raymond Hettinger가 기여했습니다.)xmlrpclib모듈은 단일 HTTP 작업에서 여러 XML-RPC 호출을 전송하기 위해 다중 호출 확장을 이제 지원합니다. (Brian Quinlan이 기여했습니다.)mpz,rotor, 및xreadlines모듈이 제거되었습니다.
doctest¶
doctest 모듈은 Edward Loper와 Tim Peters 덕분에 상당한 리팩토링을 거쳤습니다. 테스트는 여전히 doctest.testmod() 실행만큼 간단할 수 있지만, 이러한 리팩토링을 통해 모듈의 작동 방식을 다양한 방식으로 사용자 정의할 수 있습니다.
새로운 DocTestFinder 클래스는 주어진 객체의 독스트링에서 테스트를 추출합니다:
def f (x, y):
""">>> f(2,2)
4
>>> f(3,2)
6
"""
return x*y
finder = doctest.DocTestFinder()
# DocTest 인스턴스 목록 가져오기
tests = finder.find(f)
새로운 DocTestRunner 클래스는 개별 테스트를 실행하여 결과 요약을 생성할 수 있습니다:
runner = doctest.DocTestRunner()
for t in tests:
tried, failed = runner.run(t)
runner.summarize(verbose=1)
위 예제는 다음의 출력을 만듭니다:
1 items passed all tests:
2 tests in f
2 tests in 1 items.
2 passed and 0 failed.
Test passed.
DocTestRunner`는 :class:`OutputChecker 인스턴스를 사용하여 예상 출력과 실제 출력을 비교합니다. 이 클래스는 동작을 사용자 정의하는 여러 개의 플래그를 받으며, 진보적인 사용자는 :class:`OutputChecker`의 완전히 새로운 하위 클래스를 작성할 수도 있습니다.
기본 출력 검사기는 여러 유용한 기능을 제공합니다. 예를 들어, doctest.ELLIPSIS 옵션 플래그를 사용하면 예상 출력의 엘립시스(”…”)는 임의의 문자열을 일치시키므로 사소하게 다른 출력을 수용하기가 더 쉽습니다:
def o (n):
""">>> o(1)
<__main__.C instance at 0x...>
>>>
"""
또 다른 특수 문자열인 <BLANKLINE> 은 빈 줄과 일치합니다:
def p (n):
""">>> p(1)
<BLANKLINE>
>>>
"""
다른 새로운 기능은 doctest.REPORT_UDIFF (통합 diff), doctest.REPORT_CDIFF (컨텍스트 diff) 또는 doctest.REPORT_NDIFF (델타 스타일) 옵션 플래그를 지정하여 출력의 diff 스타일 출력을 생성하는 것입니다. 예를 들면:
def g (n):
""">>> g(4)
here
is
a
lengthy
>>>"""
L = 'here is a rather lengthy list of words'.split()
for word in L[:n]:
print word
위 함수를 doctest.REPORT_UDIFF 지정하여 실행하면 다음 출력을 얻습니다:
**********************************************************************
File "t.py", line 15, in g
Failed example:
g(4)
Differences (unified diff with -expected +actual):
@@ -2,3 +2,3 @@
is
a
-lengthy
+rather
**********************************************************************
빌드 및 C API 변경사항¶
파이썬의 빌드 프로세스와 C API에 대한 몇 가지 변경 사항은 다음과 같습니다:
확장 함수에서 일반적인 반환값에 대해 세 개의 새로운 편의 매크로인
Py_RETURN_NONE,Py_RETURN_TRUE, 및 :c:macro:`Py_RETURN_FALSE`가 추가되었습니다. (Brett Cannon 기고.)또 다른 새로운 매크로인
Py_CLEAR는 obj 의 참조 횟수를 감소시키고 obj 를 널 포인터로 설정합니다. (Jim Fulton 기고.)새로운 함수
PyTuple_Pack(N, obj1, obj2, ..., objN)은 Python 객체의 가변 길이 인자 목록으로부터 튜플을 생성합니다. (Raymond Hettinger 기고.)새로운 함수
PyDict_Contains(d, k)는 조회 과정에서 발생하는 예외를 마스킹하지 않고 빠른 딕셔너리 조회를 구현합니다. (Raymond Hettinger 기고.)Py_IS_NAN(X) 매크로는 그 float 또는 double 인자 X 가 NaN인 경우 1을 반환합니다. (Tim Peters 기고.)
C 코드는 새로운
PyEval_ThreadsInitialized()함수를 사용하여 스레드 작업이 수행되었는지 여부를 알려줌으로써 불필요한 잠금 기능을 피할 수 있습니다. 이 함수가 false를 반환하면 록 작업이 필요하지 않습니다. (Nick Coghlan 기고.)새로운 함수 :c:func:`PyArg_VaParseTupleAndKeywords`는 :c:func:`PyArg_ParseTupleAndKeywords`와 같지만, 인자 개수 대신 :c:type:`va_list`를 받습니다. (Greg Chapman 기고.)
새로운 메서드 플래그인 :c:macro:`METH_COEXIST`는 슬롯에서 정의된 함수가 동일한 이름을 가진 :c:type:`PyCFunction`과 공존할 수 있도록 합니다. 이는 :meth:`set.__contains__`와 같은 메서드의 접근 시간을 절반으로 줄일 수 있습니다. (Raymond Hettinger 기고.)
이제 Python은 인터프리터 자체에 대한 추가 프로파일링을 사용하여 빌드될 수 있으며, 이는 파이썬 코어 개발자들의 도움을 주기 위한 것입니다. configure 스크립트에
--enable-profiling`을 제공하면 :program:`gprof`로 인터프리터를 프로파일할 수 있고, :option:!–with-tsc` 스위치를 제공하면 Pentium의 Time-Stamp-Counter 레지스터를 사용하여 프로파일링을 활성화합니다. 참고로--with-tsc스위치는 약간 잘못된 이름인데, 왜냐하면 이 프로파일링 기능은 PowerPC 플랫폼에서도 작동하기 때문이며, 해당 프로세서 아키텍처는 그 레지스터를 “TSC 레지스터”라고 부르지 않기 때문입니다. (Jeremy Hylton 기고.)tracebackobject타입이 :c:type:`PyTracebackObject`으로 이름이 변경되었습니다.
플랫폼별 변경 사항¶
Windows 포트는 버전 6뿐만 아니라 MSVC++ 7.1에서도 빌드됩니다. (Martin von Löwis 기고.)
Python 2.4로 이식하기¶
이 섹션은 코드 변경이 필요할 수 있는 이전에 설명된 변경 사항 목록을 담고 있습니다:
좌측 시프트 및 범위 외부의 16진수/8진수 상수는 더 이상 :exc:`FutureWarning`을 트리거하지 않으며, 32비트 또는 64비트로 제한된 값을 반환하는 대신 긴 정수를 반환합니다.
정수 연산은 더 이상
OverflowWarning`을 발생시키지 않습니다. :exc:`OverflowWarning경고는 Python 2.5에서 사라집니다.zip()빌트인 함수와itertools.izip`은 이제 인수가 없을 때 :exc:`TypeError()예외를 발생하는 대신 빈 리스트를 반환합니다.datetime모듈에서 제공하는date및datetime인스턴스를 더 이상 비교할 수 없습니다. 이제 서로 다른 클래스의 두 인스턴스는 항상 같지 않으며, 상대적인 비교(<,>)는 :exc:`TypeError`를 발생시킵니다.:func:`!dircache.listdir`은 이제 빈 리스트를 반환하는 대신 예외를 호출자에게 전달합니다.
:func:`LexicalHandler.startDTD`는 이전에 공개 및 시스템 ID를 잘못된 순서로 받았습니다. 이는 수정되었으며, 잘못된 순서에 의존하는 응용 프로그램은 수정해야 합니다.
:func:`fcntl.ioctl`은 이제 mutate 인수가 생략되었고 관련이 있을 경우 경고합니다.
tarfile모듈은 이제 기본적으로 GNU 형식의 tar 파일을 생성합니다.모듈을 임포트하는 중 실패가 발생하더라도 더 이상
sys.modules에 부분적으로 초기화된 모듈 객체가 남지 않습니다.Noneis now a constant; code that binds a new value to the nameNoneis now a syntax error.signals.signal()함수는 특정 불법 값에 대해 이제RuntimeError예외를 발생시킵니다. 이전에는 이러한 오류가 조용히 지나갔습니다. 예를 들어, 더 이상SIGKILL신호에 핸들러를 설정할 수 없습니다.
감사의 글¶
필자는 이 글의 다양한 초안을 제안하고 수정하며 도움을 준 다음 분들에게 감사드립니다: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, Sadruddin Rejeb.