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는 두 가지 측면에서 더 간단합니다.
근거
Python은 현재 C의 printf() ‘%’ 형식 지정 문자를 기반으로 하는 문자열 치환 구문을 지원합니다 [1]. %-형식 지정 코드는 기능이 매우 풍부하지만, 숙련된 Python 프로그래머에게도 오류가 발생하기 쉽습니다. 흔히 발생하는 실수는 끝의 형식 지정 문자를 빠뜨리는 것입니다. 예를 들어 "%(name)s"의 ‘s’가 이에 해당합니다.
또한 % 기호 뒤에 올 수 있는 항목에 대한 규칙은 상당히 복잡하지만, 일반적인 사용에서는 그러한 복잡성이 거의 필요하지 않습니다. 대부분의 스크립트는 문자열 보간을 수행해야 하지만, 대부분은 간단한 ‘문자열화’ 형식, 즉 %s 또는 %(name)s를 사용합니다. 이 형식은 더 간단하고 오류가 발생하기 어렵게 만들어야 합니다.
더 간단한 제안
string 모듈에 포함될 Template라는 새 클래스를 추가할 것을 제안합니다. Template 클래스는 문자열 치환을 위한 새로운 규칙을 지원하며, 그 값에는 $ 문자로 도입되는 자리표시자가 포함됩니다. $ 자리표시자에는 다음 규칙이 적용됩니다.
$$는 이스케이프이며, 하나의$로 치환됩니다.$identifier는 매핑 키가 “identifier”인 치환 자리표시자를 나타냅니다. 기본적으로 “identifier”는 [2]에 정의된 Python 식별자여야 합니다.$문자 뒤에 오는 첫 번째 식별자가 아닌 문자가 이 자리표시자 지정을 끝냅니다.${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 소스 트리에 커밋되었습니다.
참고 문헌
Copyright
This document has been placed in the public domain.