Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 682 – 부호 있는 0을 위한 형식 지정자

Author:
John Belmonte <john at neggie.net>
Sponsor:
Mark Dickinson <dickinsm at gmail.com>
PEP-Delegate:
Mark Dickinson
Discussions-To:
Discourse thread
Status:
Final
Type:
Standards Track
Created:
29-Jan-2022
Python-Version:
3.11
Post-History:
08-Feb-2022
Resolution:
Discourse thread

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

floatDecimal형식은 signed zero를 나타낼 수 있지만, 수학의 많은 분야에서 음의 0은 놀랍거나 원치 않는 것입니다. 특히 (흔히 반올림된) 수치 결과를 표시하는 맥락에서는 더욱 그렇습니다. 이 PEP는 음의 0을 양의 0으로 정규화할 수 있도록 string format specification을 확장할 것을 제안합니다.

동기

음의 0은 다음과 같습니다.:

>>> x = -0.
>>> x
-0.0

숫자를 형식화할 때 음의 0은 반올림으로 인해 발생할 수 있습니다. 사용자의 의도가 정말로 정밀도를 버리는 것이라고 가정하면, 반올림된 결과에서 음의 0과 양의 0을 구분하는 것은 원치 않는 부산물로 간주할 수 있습니다.:

>>> for x in (.002, -.001, .060):
...     print(f'{x: .1f}')
 0.0
-0.0
 0.1

음의 0의 부호를 제거하는 방법은 여러 가지가 있습니다. 양의 0을 더하면 조건문 없이 이를 수행할 수 있습니다.:

>>> x = -0.
>>> x + 0.
0.0

형식화할 때 음의 0을 정규화하려면 입력을 중복해서 (오류가 발생하기 쉬운 방식으로) 사전 반올림해야 합니다.:

>>> for x in (.002, -.001, .060):
...     print(f'{round(x, 1) + 0.: .1f}')
 0.0
 0.0
 0.1

언어와 관계없이 프로그래머들이 음의 0을 억제할 방법을 자주 찾고 있으며, 다양한 우회 방법(사전 반올림, 사후 정규식 처리 등)을 사용하게 된다는 충분한 증거가 있습니다. 몇 가지 예는 다음과 같습니다.

대신 수치 문자열 형식화가 이미 제공하는 다른 모든 기능에 더해, 음의 0을 정규화하는 일급 옵션을 원합니다.

근거

형식화된 숫자 출력에서 음의 0을 원하지 않는 사용 사례가 있으며, 그렇게 원하지 않는 경우가 더 일반적이라고 볼 수 있습니다. 숫자 형식화에는 이미 반올림이 포함되어 있고 음의 0의 정규화는 반올림 후에 이루어져야 하므로, 형식 지정을 확장하는 것이 이를 지원하는 가장 좋은 방법입니다.

형식화하기 전에 숫자를 사전 반올림하고 정규화할 수는 있지만, 반올림이 형식 지정의 반올림과 정확히 일치하지 않으면 번거롭고 오류가 발생하기 쉽습니다. 또한 형식화를 감싸는 함수는 정밀도 정보를 추출하기 위해 형식 지정을 구문 분석해야 합니다. 예를 들어, 일차원 수치 배열을 형식화하는 이 유틸리티가 이러한 사전 반올림으로 인해 어떻게 복잡해질지 생각해 보십시오.

def format_vector(v, format_spec='8.2f'):
    """Format a vector (any iterable) using given per-term format string."""
    return f"[{','.join(f'{term:{format_spec}}' for term in v)}]"

현재까지 음의 0을 위한 형식화 옵션을 제공하는 널리 사용되는 다른 언어나 라이브러리는 없는 것으로 보입니다. 그러나 아래에 지정된 것과 동일한 z 옵션의 구문과 의미가 proposed for C++ std::format()되었습니다. 이 제안은 C++20을 위해서는 철회되었지만, C++23을 위한 합의된 제안이 약속되어 있습니다. (이 PEP를 촉발한 원래의 feature request는 C++ 제안을 알지 못한 상태에서 논의되었습니다.)

Rust 개발자들은 print 출력에서 음의 0을 억제할지 논의하면서 소규모 survey of other languages를 진행했습니다. 특히 음의 0 처리를 위한 옵션을 제공하는 언어는 언급하지 않았습니다.

사양

선택적인 리터럴 zsign뒤에 이어지는 Format Specification Mini-Language에 추가합니다:

[[fill]align][sign][z][#][0][width][grouping_option][.precision][type]

z가 부동 소수점 표시 형식(f, g 등, 형식 지정 문서에 정의된 형식)에 허용되는 경우입니다. z에 대한 지원은 각 숫자 형식의 .__format__() 메서드에서 제공되므로, 지정자를 f-문자열, 내장 format(), str.format()에서 사용할 수 있게 합니다.

z가 있으면 원래 값이 음의 0이든 반올림 결과가 음의 0이든 음의 0을 양의 0으로 정규화합니다.

개요:

>>> x = -.00001
>>> f'{x:z.1f}'
'0.0'

>>> x = decimal.Decimal('-.00001')
>>> '{:+z.1f}'.format(x)
'+0.0'

설계 참고 사항

숫자 형식을 지정할 때 음의 0을 예상하거나 이에 의존할 수 있는 프로그램의 동작을 변경할 수 없으므로, 이 해결책은 옵트인 방식이어야 합니다.

제안된 확장은 의도적으로 [sign][z]이며, [sign[z]]가 아닙니다. sign의 기본값(-)은 널리 알려져 있거나 명시적으로 작성되어 있지 않으므로, 이렇게 하면 모든 사람이 z 옵션을 사용하기 위해 기본값을 배울 필요가 없습니다.

f-문자열, 내장 format(), str.format()에서는 새 옵션에 접근할 수 있지만, %-형식 지정에서는 접근할 수 없습니다. 새 옵션으로 %-형식 지정을 확장하지 않은 전례가 이미 있으며, ,옵션(PEP 378)이 그 사례입니다.

C99 printf는 이미 다른 목적으로 z 옵션 문자를 사용합니다. 즉, 부호 없는 형식(u)의 길이를 size_t의 길이에 맞추도록 지정합니다. 그러나 부호 있는 0 옵션에서는 정수 표시 형식에 z를 허용하지 않으므로, C에서 이 새 옵션을 채택하려는 경우 두 용도를 구분할 수 있습니다.

하위 호환성

새로운 형식 지정 동작은 옵트인 방식이므로 기존 프로그램의 수치 형식 지정에는 영향을 주지 않습니다.

이 내용을 가르치는 방법

일반적인 Python 입문 과정에서는 문자열 형식을 자세히 다루지 않습니다. 그러한 과정에는 아무런 조정도 필요하지 않습니다. 문자열 형식 지정 사양의 세부 사항까지 다루는 과정이라면, 형식 지정에 의해 0으로 반올림되는 음수 값에 z옵션이 미치는 효과를 보여 주는 예시 하나면 충분합니다. 다른 사람의 코드에서 이 기능을 접한 독립 개발자라면 라이브러리 참고 매뉴얼의 Format Specification Mini-Language 섹션을 참조하는 것으로 충분합니다.

참조 구현

참조 구현은 pull request #30049에 있습니다.