PEP 461 – bytes 및 bytearray에 % 서식 지정을 추가하기
- Author:
- Ethan Furman <ethan at stoneleaf.us>
- Status:
- Final
- Type:
- Standards Track
- Created:
- 13-Jan-2014
- Python-Version:
- 3.5
- Post-History:
- 14-Jan-2014, 15-Jan-2014, 17-Jan-2014, 22-Feb-2014, 25-Mar-2014, 27-Mar-2014
- Resolution:
- Python-Dev message
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 Python 2의 str형식과 유사한 % 서식 지정 연산을 bytes 및 bytearray에 추가할 것을 제안합니다 [1] [2].
근거
보간은 일반적으로 문자열 연산으로 간주되지만, bytes 또는 bytearray에 보간을 적용하는 것이 타당한 경우가 있으며, 이 누락된 기능을 보완하는 데 필요한 작업은 코드의 전반적인 가독성을 저해합니다.
동기
Python 3과 str 및 bytes의 분리로 인해 작지만 중요한 프로그래밍 영역이 조금 더 어려워졌으며, 훨씬 더 고통스러워졌습니다 – 와이어 형식 프로토콜 [3]입니다.
이 프로그래밍 영역은 바이너리 데이터와 ASCII 호환 텍스트 세그먼트(즉, ASCII로 인코딩된 텍스트)가 혼합되어 있다는 특징이 있습니다. bytes 및 bytearray를 위한 제한된 % 보간을 다시 도입하면 새로운 와이어 형식 코드를 작성하고 Python 2 와이어 형식 코드를 포팅하는 데 모두 도움이 됩니다.
일반적인 사용 사례로는 dbf 및 pdf 파일 형식, email 형식, FTP 및 HTTP 통신 등이 있으며, 이 밖에도 많습니다.
bytes 및 bytearray 형식 지정에 대해 제안된 의미 체계
% 보간
모든 숫자 형식 지정 코드(d, i, o, u, x, X, e, E, f, F, g, G 및 이후 Python 3에 추가되는 모든 코드)가 지원되며, 패딩, 정렬 및 기타 관련 수정자(현재는 #, 0, -, 공백 및 +이며, Python 3에 추가되는 항목도 포함)를 비롯하여 str에서와 동일하게 작동합니다. 허용되는 유일한 비수치 코드는 c, b, a, 및 s(이는 b의 동의어입니다)입니다.
숫자 코드에서 str과 bytes(또는 bytearray)의 보간 사이의 유일한 차이점은 이러한 코드의 결과가 유니코드가 아닌 ASCII로 인코딩된 텍스트라는 점입니다. 다시 말해, 모든 숫자 형식 지정 코드 %x:
b"%x" % val
다음과 동등합니다:
("%x" % val).encode("ascii")
예제:
>>> b'%4x' % 10
b' a'
>>> b'%#4x' % 10
' 0xa'
>>> b'%04X' % 10
'000A'
%c는 256 미만 범위의 int에서 가져오거나 길이가 1인 bytes 인자에서 가져온 단일 바이트를 삽입하며, str에서는 가져오지 않습니다.
예제:
>>> b'%c' % 48
b'0'
>>> b'%c' % b'a'
b'a'
%b는 일련의 바이트를 삽입합니다. 이러한 바이트는 다음 두 가지 방법 중 하나로 수집됩니다.
- 입력 형식이
Py_buffer[4]를 지원합니까? 필요한 바이트를 수집하는 데 사용합니다. - 입력 형식이 다른 것입니까? 해당 형식의
__bytes__메서드 [5]를 사용하며, 메서드가 없으면TypeError를 발생시킵니다.
특히, %b는 숫자나 str을 허용하지 않습니다. str은 문자열을 바이트로 변환하려면 인코딩이 필요하고 이를 추측하지 않기로 했기 때문에 거부되며, 숫자는 다음과 같은 이유로 거부됩니다:
- 무엇을 숫자로 간주할지가 모호합니다(float? Decimal? Fraction? 일부 사용자 정의 형식?)
- 숫자를 허용하면 숫자와 숫자의 텍스트 표현(3.14와 ‘3.14’) 사이에 모호성이 생깁니다.
- 와이어 형식의 특성을 고려하면 명시적인 방식이 암시적인 방식보다 확실히 낫습니다.
%s는 2/3 코드베이스를 더 쉽게 유지 관리할 수 있도록 하기 위한 유일한 목적으로 %b의 동의어로 포함됩니다. Python 3 전용 코드는 %b를 사용해야 합니다.
예제:
>>> b'%b' % b'abc'
b'abc'
>>> b'%b' % 'some string'.encode('utf8')
b'some string'
>>> b'%b' % 3.14
Traceback (most recent call last):
...
TypeError: b'%b' does not accept 'float'
>>> b'%b' % 'hello world!'
Traceback (most recent call last):
...
TypeError: b'%b' does not accept 'str'
%a는 보간된 값에 대해 repr(some_obj).encode('ascii', 'backslashreplace')와 동등한 결과를 제공합니다. 사용 사례로는 새 프로토콜을 개발하고 스트림에 랜드마크를 기록하는 경우, 기존 프로토콜로 전달되는 데이터를 디버깅하여 문제가 프로토콜 자체에 있는지 잘못된 데이터에 있는지 확인하는 경우, 직렬화 형식의 대체 수단, 또는 __bytes__를 정의하는 것이 적절하지 않지만 읽기 쉽고 유익한 표현이 필요한 모든 상황이 있습니다 [6].
%r는 2/3 코드베이스의 유지 관리를 쉽게 하는 유일한 목적으로 %a의 동의어로 포함됩니다. Python 3 전용 코드에서는 %a를 사용하십시오 [7].
예제:
>>> b'%a' % 3.14
b'3.14'
>>> b'%a' % b'abc'
b"b'abc'"
>>> b'%a' % 'def'
b"'def'"
Python 2와의 호환성
위에서 언급했듯이 %s와 %r는 Python 2에서의 마이그레이션을 용이하게 하거나 Python 2와 단일 코드베이스를 유지하는 데 도움을 주기 위한 목적으로만 포함됩니다. 이는 현재도 공개적으로 사용되거나 비공개적으로 사용되는 모듈 중에 Python 2의 str유형을 bytes컨테이너로 사용하고 그에 따라 %s를 바이트 보간자로 사용하는 모듈이 있기 때문에 중요합니다.
그러나 새 Python 3 전용 코드에서는 %b와 %a를 사용해야 하므로 %s와 %r는 즉시 사용 중단 예정이 되지만 3.x 계열에서 제거되지는 않습니다 [7].
제안된 변형
%b에 대한 str인자에 .encode('ascii','strict')를 자동으로 사용하자는 제안이 있었습니다.
- 이는 간헐적인 실패로 이어지므로 거부되었습니다. 문제가 발생한 지점을 올바르게 수정할 수 있도록 연산이 항상 실패하게 하는 편이 낫습니다.
값이 str일 때 %b가 ASCII로 인코딩된 repr을 반환하도록 하자는 제안이 있었습니다 (b’%b’ % ‘abc’ –> b“‘abc’”).
- 이는 문제 지점에서 멀리 떨어진 곳에서 디버깅하기 어려운 실패로 이어지므로 거부되었습니다. 문제가 발생한 지점을 쉽게 수정할 수 있도록 연산이 항상 실패하게 하는 편이 낫습니다.
원래 이 PEP에서는 형식 스타일의 포매팅도 추가하자고 제안했지만, format과 관련 메커니즘은 모두 엄격하게 텍스트(즉, str 기반)였기 때문에 이를 제외하기로 결정했습니다.
__ascii__, __format_bytes__ 등과 같은 다양한 새 특수 메서드가 제안되었지만, 현재로서는 이러한 메서드가 필요하지 않으며 실제 사용을 통해 이 해결책의 결함이 드러날 경우 나중에 다시 검토할 수 있습니다.
경쟁 PEP인 PEP 460 Add binary interpolation and formatting도 존재합니다.
반대 의견
이 PEP에 제기된 반대 의견은 주로 다음 두 가지 주제의 변형이었습니다.
bytes및bytearray유형은 인코딩에 대한 어떠한 가정도 하지 않는 순수 바이너리 데이터를 위한 것입니다.- ASCII 인코딩을 가정하는 %-보간을 제공하면 매력적인 골칫거리가 되어 Python 2의
str/unicode텍스트 모델 문제로 되돌아가게 됩니다.
논의 과정에서 확인되었듯이 bytes 및 bytearray는 혼합 바이너리 데이터와 ASCII 호환 세그먼트에도 사용됩니다. 예를 들어 dbf 및 pdf와 같은 파일 형식과 ftp 및 email과 같은 네트워크 프로토콜이 있습니다.
bytes 및 bytearray에는 이미 ASCII 호환 인코딩을 가정하는 메서드가 여러 개 있습니다. 몇 가지만 예로 들면 upper(), isalpha(), expandtabs()가 있습니다. 매우 제한적인 미니 언어를 사용하는 %-보간은 이미 존재하는 메서드보다 더 큰 골칫거리가 되지 않습니다.
십진수만으로 충분하다는 주장과 함께 전체 숫자 포매팅 코드 범위를 허용하는 것에 반대하는 사람들도 있었습니다. 그러나 최소한 두 가지 형식(dbf 및 pdf)은 십진수가 아닌 숫자를 사용합니다.
각주
Copyright
This document has been placed in the public domain.