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

Python 개선 제안 한국어 번역

PEP 292 – 더 간단한 문자열 치환

Author:
Barry Warsaw <barry at python.org>
Status:
Final
Type:
Standards Track
Created:
18-Jun-2002
Python-Version:
2.4
Post-History:
18-Jun-2002, 23-Mar-2004, 22-Aug-2004
Replaces:
215

Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 문자열 보간이라고도 하는 더 간단한 문자열 치환 기능을 설명합니다. 이 PEP는 두 가지 측면에서 더 간단합니다.

  1. Python의 현재 문자열 치환 기능(즉, %-치환)은 복잡하고 오류가 발생하기 쉽습니다. 이 PEP는 일부 표현력을 희생하는 대신 더 간단합니다.
  2. PEP 215는 새로운 $ 문자열 접두사를 도입하는 대체 문자열 보간 기능을 제안했습니다. PEP 292는 구문 변경이 필요하지 않고 문자열에서 발생할 수 있는 치환에 대한 규칙도 훨씬 간단하므로 이보다 더 간단합니다.

근거

Python은 현재 C의 printf()%’ 형식 지정 문자를 기반으로 하는 문자열 치환 구문을 지원합니다 [1]. %-형식 지정 코드는 기능이 매우 풍부하지만, 숙련된 Python 프로그래머에게도 오류가 발생하기 쉽습니다. 흔히 발생하는 실수는 끝의 형식 지정 문자를 빠뜨리는 것입니다. 예를 들어 "%(name)s"의 ‘s’가 이에 해당합니다.

또한 % 기호 뒤에 올 수 있는 항목에 대한 규칙은 상당히 복잡하지만, 일반적인 사용에서는 그러한 복잡성이 거의 필요하지 않습니다. 대부분의 스크립트는 문자열 보간을 수행해야 하지만, 대부분은 간단한 ‘문자열화’ 형식, 즉 %s 또는 %(name)s를 사용합니다. 이 형식은 더 간단하고 오류가 발생하기 어렵게 만들어야 합니다.

더 간단한 제안

string 모듈에 포함될 Template라는 새 클래스를 추가할 것을 제안합니다. Template 클래스는 문자열 치환을 위한 새로운 규칙을 지원하며, 그 값에는 $ 문자로 도입되는 자리표시자가 포함됩니다. $ 자리표시자에는 다음 규칙이 적용됩니다.

  1. $$는 이스케이프이며, 하나의 $로 치환됩니다.
  2. $identifier는 매핑 키가 “identifier”인 치환 자리표시자를 나타냅니다. 기본적으로 “identifier”는 [2]에 정의된 Python 식별자여야 합니다. $ 문자 뒤에 오는 첫 번째 식별자가 아닌 문자가 이 자리표시자 지정을 끝냅니다.
  3. ${identifier}$identifier와 동일합니다. 자리표시자 뒤에 유효한 식별자 문자가 이어지지만 해당 자리표시자의 일부가 아닌 경우에 필요합니다. 예를 들어 "${noun}ification"과 같습니다.

$ 문자가 줄 끝에 나타나거나 위에서 설명한 문자 이외의 문자가 뒤따르면 보간 시점에 ValueError가 발생합니다. 매핑의 값은 자동으로 문자열로 변환됩니다.

그 밖의 문자에는 특별한 의미가 없지만, Template 클래스를 상속하여 다른 치환 규칙을 정의할 수 있습니다. 예를 들어 파생 클래스에서 자리표시자에 마침표를 허용하거나(동적 네임스페이스와 속성 경로 조회의 일종을 지원하기 위해), $ 이외의 문자를 구분자로 정의할 수 있습니다.

Template를 생성한 후에는 두 메서드 중 하나를 호출하여 치환을 수행할 수 있습니다.

  • substitute(). 이 메서드는 매핑의 값이 Template의 자리표시자를 대신할 때 생성되는 새 문자열을 반환합니다. 매핑에 존재하지 않는 자리표시자가 있으면 KeyError가 발생합니다.
  • safe_substitute(). 이는 substitute() 메서드와 유사하지만, 매핑에 플레이스홀더가 없더라도 KeyErrors가 발생하지 않습니다. 플레이스홀더가 없으면 원래 플레이스홀더가 결과 문자열에 나타납니다.

    다음은 몇 가지 예입니다.:

    >>> from string import Template
    >>> s = Template('${name} was born in ${country}')
    >>> print s.substitute(name='Guido', country='the Netherlands')
    Guido was born in the Netherlands
    >>> print s.substitute(name='Guido')
    Traceback (most recent call last):
    [...]
    KeyError: 'country'
    >>> print s.safe_substitute(name='Guido')
    Guido was born in ${country}
    

substitute()safe_substitute()의 시그니처를 사용하면 첫 번째 위치 인자에 단일 딕셔너리와 유사한 객체로 전달하거나, 위에 보인 것처럼 키워드 인자로 전달하여 플레이스홀더와 값의 매핑을 지정할 수 있습니다. 이 두 메서드의 정확한 세부 사항과 시그니처는 표준 라이브러리 문서에서 다룹니다.

$와 중괄호인가?

BDFL이 가장 잘 표현했습니다 [3]: “Perl 외에도 $가 ‘치환’을 의미하는 언어가 아주 많으니, 지금까지 어디에 계셨는지 궁금합니다. […] 셸에서 이를 가져오는 것입니다.”

따라서 치환 규칙은 다른 여러 언어와 유사하기 때문에 선택되었습니다. 이로 인해 치환 규칙을 가르치고, 배우고, 기억하기가 더 쉬워집니다.

PEP 215와의 비교

PEP 215는 문자열 보간에 대한 대안 제안을 설명합니다. 해당 PEP와 달리 이 PEP는 Python에 새로운 구문을 제안하지 않습니다. 제안된 모든 새로운 기능은 새로운 라이브러리 모듈에 구현됩니다. PEP 215$""와 같은 새로운 문자열 접두사 표현을 제안하며, 이는 새로운 유형의 문자열이 존재함을 Python에 알립니다. $-문자열은 기존 r-접두사 및 u-접두사와 상호 작용해야 하므로, 본질적으로 문자열 접두사 조합의 수가 두 배가 됩니다.

또한 PEP 215$-문자열 내부에서 임의의 Python 표현식을 사용할 수 있도록 하므로, 다음과 같은 작업을 수행할 수 있습니다.:

import sys
print $"sys = $sys, sys = $sys.modules['sys']"

그러면 다음을 반환합니다.:

sys = <module 'sys' (built-in)>, sys = <module 'sys' (built-in)>

일반적으로 PEP 215의 규칙은 새로운 보안 문제를 도입하지 않는다는 의미에서 안전한 것으로 인정됩니다(자세한 내용은 PEP 215의 “보안 문제”를 참조하십시오). 그러나 규칙은 여전히 상당히 복잡하며, 원래 $-문자열에서 치환 플레이스홀더를 확인하기가 더 어려워집니다.

흥미로운 점은 이 PEP에서 정의한 Template 클래스가 상속을 염두에 두고 설계되었으며, 약간의 추가 작업을 하면 기존 Python 구문을 사용하여 PEP 215의 기능을 지원할 수 있다는 것입니다.

예를 들어 더 복잡한 플레이스홀더 구문과 해당 플레이스홀더를 평가하는 매핑을 지원하는 Template 및 dict의 서브클래스를 정의할 수 있습니다.

국제화

구현은 원래 템플릿 문자열을 Template 인스턴스의 template 특성에 기록하여 국제화를 지원합니다. 이 특성은 gettext 기반 카탈로그에서 조회 키로 사용됩니다. 결과 문자열을 치환을 위해 다시 Template으로 변환하는 것은 애플리케이션의 책임입니다.

그러나 Template 클래스는 Template과 unicode 서브클래스를 혼합해 상속할 수 있도록 지원하여 국제화된 애플리케이션에서 더욱 직관적으로 작동하도록 설계되었습니다. 따라서 국제화된 애플리케이션은 Template과 unicode를 다중 상속하는 애플리케이션별 서브클래스를 만들고, 해당 서브클래스의 인스턴스를 gettext 카탈로그 키로 사용할 수 있습니다. 또한 이 서브클래스는 특수한 __mod__() 메서드를 .substitute() 또는 .safe_substitute() 중 하나의 별칭으로 지정하여, 보다 전통적인 문자열/유니코드와 유사한 % 연산자 치환 구문을 제공할 수 있습니다.

참조 구현

구현 [4]이 Python 2.4 소스 트리에 커밋되었습니다.

참고 문헌