# PEP 750 – 템플릿 문자열(t-strings) 승인

> Clean Markdown view of GeekNews topic #20266. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=20266](https://news.hada.io/topic?id=20266)
- GeekNews Markdown: [https://news.hada.io/topic/20266.md](https://news.hada.io/topic/20266.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-04-11T10:17:36+09:00
- Updated: 2025-04-11T10:17:36+09:00
- Original source: [peps.python.org](https://peps.python.org/pep-0750/)
- Points: 2
- Comments: 3

## Topic Body

- PEP 750은 Python에 새로운 문자열 리터럴인 **템플릿 문자열(`t"..."`)** 을 도입함  
- f-string의 일반화된 형태로, `Template` 타입을 생성하여 문자열과 삽입 값을 결합 전 처리할 수 있는 기능 제공  
- 웹 템플릿, 보안 검사, DSL(Domain-Specific Language) 등에 유용하게 사용 가능함  
  
### 다른 PEP들과의 관계  
  
- f-string은 PEP 498로 도입되었고, PEP 701에서 문법이 확장됨  
- PEP 501은 일반 템플릿 문자열(`i-string`)을 제안했지만 보류됨  
- 현재 PEP 750은 PEP 501을 단순화 및 일반화한 형태로, 기존 아이디어를 기반으로 발전됨  
  
### 동기 및 필요성  
  
- f-string은 간단하지만, 삽입 값을 사전에 가공할 수 없어 보안상 문제 발생 가능  
- SQL 삽입, XSS 공격 등 보안 취약점 유발 우려 있음  
- 템플릿 문자열을 사용하면 삽입 값을 사전에 가공하여 안전하게 사용할 수 있음  
  
예시:  
  
- `evil = "&lt;script&gt;alert('evil')&lt;/script&gt;"`  
- `template = t"&lt;p&gt;{evil}&lt;/p&gt;"`  
- `assert html(template) == "&lt;p&gt;&lt;script&gt;alert('evil')&lt;/script&gt;&lt;/p&gt;"`  
  
### 템플릿 문자열의 사양  
  
#### 템플릿 문자열 리터럴  
  
- 접두사 `t` 또는 `T`를 사용해 정의  
- `string.templatelib.Template` 타입으로 평가됨  
- f-string과 유사한 문법 지원, 중첩도 가능  
- `r` 접두사와 조합 가능 (`rt`, `tr`)  
- `u`, `b` 접두사와는 조합 불가  
- f-string과 템플릿 문자열은 혼합 사용 불가  
  
#### Template 타입  
  
- 불변 타입이며, 다음 속성을 가짐:  
  - `strings`: 문자열 조각들의 튜플  
  - `interpolations`: 삽입값 객체들의 튜플  
  - `values`: 삽입값들의 값 튜플  
  - `__iter__()`: 문자열과 삽입값을 순서대로 반환하는 이터레이터  
  
#### Interpolation 타입  
  
- `value`: 평가된 결과  
- `expression`: 원래 삽입 표현식 문자열  
- `conversion`: 변환 방식 (`r`, `s`, `a` 또는 None)  
- `format_spec`: 서식 문자열  
  
예시:  
  
- `name = "World"`  
- `template = t"Hello {name!r}"`  
- `assert template.interpolations[0].conversion == "r"`  
  
#### 디버그 지정자 `=`  
  
- `t"{value=}"`는 `t"value={value!r}"`로 해석됨  
- 공백도 그대로 보존됨 (`t"{value = }"` → `"value = {value!r}"`)  
  
#### 템플릿 문자열 연결  
  
- `+` 연산자로 `Template`과 `str`, `Template` 간의 결합 가능  
- 연결 결과는 항상 `Template` 타입  
- 묵시적 문자열 연결(`t"Hello " t"World"`)도 가능  
  
### 템플릿 문자열 처리 방법  
  
#### 예시: 대문자 처리 함수  
  
- `def lower_upper(template):`  
    - `parts = []`  
    - `for s in template:`  
        - `if isinstance(s, str): parts.append(s.lower())`  
        - `else: parts.append(str(s.value).upper())`  
    - `return "".join(parts)`  
  
#### 예시: f-string과 동일한 처리 구현  
  
- `f()` 함수로 f-string과 동일한 결과 생성 가능  
  
#### 예시: 구조화된 로깅  
  
- 템플릿 문자열을 사용하면 로그 메시지와 구조화된 값들을 동시에 출력 가능  
- `StructuredMessage` 또는 `logging.Formatter` 서브클래스로 구현 가능  
  
#### 예시: HTML 템플릿 처리  
  
- `html()` 함수는 삽입 위치에 따라 내용을 적절히 escape 또는 속성으로 처리  
- 중첩 템플릿도 지원  
  
### 고급 사용 패턴  
  
- 구조적 패턴 매칭 사용 권장 (`match` 문)  
- 정적 문자열은 캐시 키로 사용, 효율적 메모이제이션 가능  
- AST 등 중간 표현으로 파싱해 처리 가능  
- Lazy 또는 Async 평가를 위해 `lambda`, `await` 사용 가능  
  
### 템플릿 문자열과 기존 포맷 문자열의 관계  
  
- 기존 `.format()`과 유사한 방식으로 템플릿 함수 정의 가능  
- 외부 문자열을 파싱하여 `Template`으로 변환하는 `from_format()`도 가능  
  
### 호환성, 보안, 학습  
  
- 구 버전 Python에서는 문법 오류 발생 가능  
- 보안상 템플릿 처리가 안전성을 높임  
- f-string과 유사한 문법으로 학습이 쉬움  
  
### 왜 새로운 템플릿 접근 방식인가?  
  
- 기존 Jinja 같은 템플릿은 사용자 정의 또는 디자이너 대상  
- 템플릿을 개발자가 직접 다룰 수 있도록 Python 언어 차원에서 지원 필요  
- 표현력과 타입 검사 등의 장점 활용 가능  
  
### 예시 패턴 정리  
  
- 구조적 패턴 매칭과 하위 속성 매칭  
- 템플릿을 함수처럼 재사용  
- 중첩 템플릿 지원  
- Lazy/Async 평가 지원  
- 정적/동적 분리로 캐시 최적화  
  
### 기타 설계 고려 사항  
  
- 템플릿은 문자열로 변환되지 않으며, `__str__()` 미구현  
- `string.templatelib` 모듈에서 관련 클래스 제공  
- `Template`, `Interpolation`은 객체 동일성 기준으로 비교됨  
- `==` 또는 `<` 연산은 지원하지 않음  
  
### 참조 구현 및 예제  
  
- [CPython 구현](https://github.com/lysnikolaou/cpython/tree/tstrings)  
- [예제 및 테스트](https://github.com/davepeck/pep750-examples) 제공  
  
### 거절된 아이디어  
  
- 임의의 접두사 사용 (`my_tag"..."`)  
- 모든 삽입 표현식의 지연 평가  
- 프로토콜로 구현  
- `__eq__`, `__hash__` 재정의  
- 원본 문자열 완전 복원  
- `Decoded` 타입 추가  
- 바이너리 템플릿 문자열 지원  
- 포맷 종류("html", "sql" 등) 지정 기능  
- 문자열 연결 제한  
- 임의의 변환자(`!x`) 허용

## Comments



### Comment 37057

- Author: carnoxen
- Created: 2025-04-11T21:19:19+09:00
- Points: 1

가장 만족스러운 포매팅은 자스와 파이썬밖에 없네요. 다른 언어는 좀...

### Comment 37036

- Author: kandk
- Created: 2025-04-11T11:53:52+09:00
- Points: 1

명확한, 그리고 가급적이면 유일한 명백한 방법이 있을 것이다. (There should be one-- and preferably only one --obvious way to do it.)

### Comment 37024

- Author: neo
- Created: 2025-04-11T10:17:36+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=43647716) 
- 다양한 언어들이 문자열 포맷팅을 다루는 방식이 흥미로움
  - Java는 f/t-strings를 추가하려고 노력 중이나, 모든 문제를 해결하려는 완벽주의로 인해 어려움을 겪고 있음
  - Go 개발자들은 이 문제를 거의 고려하지 않고 무시한 것으로 보임
  - Python은 균형 잡힌 접근 방식을 취해 새로운 문자열 포맷팅 방법을 논의하고 적절한 구현을 선택해 사용 중임
  - Python의 접근 방식에 동의하지 않을 수 없으며, .format(), f-strings, t-strings를 통해 가치를 얻고 있음

- Nick Humrich는 PEP 501을 재작성하여 t-strings를 도입한 저자 중 한 명이며, 이 PEP의 수용에 매우 기뻐하고 있음
  - 4년 전부터 PEP 501 작업을 시작했음

- 언어 수준의 기능이 가치 있는지 확신하지 못함
  - f-string을 반환하는 함수로 같은 결과를 얻을 수 있음
  - 주입 안전성을 원한다면 태그 타입과 문자열을 반환하는 정화 함수를 사용하면 됨
  - 간결하지만, 단일 문자로 즉시 실행과 지연 실행을 구분하는 것은 Python에 익숙하지 않은 사람들에게 읽기 어려움을 줄 수 있음

- f-strings를 좋아하지만, 평가를 지연할 수 없는 문제가 있음
  - str.format을 사용해야 하는 경우가 있어 불편함

- lit-html의 유지보수자로서 JavaScript의 태그 템플릿 리터럴과 유사한 점이 흥미로움
  - Python의 Template 클래스가 JavaScript의 태그 함수와 인수를 분리하는 방식이 독특함
  - 중첩된 템플릿 구조에서 html() 함수가 필요하지 않을 수 있음

- JavaScript의 태그 템플릿 리터럴이 HTML 자동 이스케이프나 SQL 매개변수화에 도움이 되는 점이 Python에도 적용될 것 같아 기대됨

- Python이 PHP로 변하는 것 같다는 의견
  - f-strings와 t-strings가 언어에 복잡성을 더함
  - string.format이 최적이라고 생각하며, %도 오랫동안 사용되어 온 만큼 수용 가능함
  - 언어 팀이 더 중요한 것에 집중하길 바람

- 언어에 계속해서 새로운 것을 추가하는 것에 대한 불만
  - 언어가 위원회에 의해 설계된 것처럼 느껴짐

- 이 PEP가 C++의 P1819와 유사하다는 의견

- PEP의 코드가 너무 장황하다는 의견
  - Python이 실행 가능한 의사 코드가 아닌 과도한 불필요함을 표현하는 것 같음
  - Ruby의 코드와 비교하여 Python 코드가 더 장황함
