사람의 이름과 직업을 출력하고 싶다고 가정해 보겠습니다. 다음과 같이 간단한 프로그램을 작성할 수 있습니다.
# 변수 정의 name = 'Mark' profession = 'Astronaut' age = 7 # 정보 출력 output_string = ('My name is ' + name + ', I am ' + str(age) + ' years old ' + 'and my profession is ' + profession + '.') print(output_string)
My name is Mark, I am 7 years old and my profession is Astronaut.
이 접근 방식은 간결성과 가독성이 부족합니다. 다행히도, 문자열 보간(string interpolation)은 더 나은 솔루션을 제공합니다. 이는 변수, 표현식 또는 함수 출력을 문자열에 직접 삽입할 수 있게 하여 문자열 조작을 동적으로 만들고 수동 연결의 필요성을 없애줍니다.
문자열 보간 접근 방식을 사용하여 코드를 다음과 같이 다시 작성할 수 있습니다.
# 변수 정의 name = 'Mark' profession = 'Astronaut' age = 7 # 정보 출력 output_string = f'My name is {name}, I am {age} years old and my profession is {profession}.' print(output_string)
My name is Mark, I am 7 years old and my profession is Astronaut.
문자열 보간이 적용된 버전은 복잡한 연결 없이 문자열 내부에 표현식을 직접 삽입할 수 있습니다. 보시다시피, 훨씬 더 깔끔한 접근 방식입니다.
파이썬의 기본 문자열 보간
파이썬에는 여러 가지 문자열 보간 기법이 있습니다. 가장 일반적으로 추천되는 방법은 포맷된 문자열 리터럴, 즉 f-strings로, 이는 파이썬 3.6부터 사용할 수 있었습니다.
또 다른 방법은 Python 3.6 이전의 코드에서 흔히 볼 수 있는 .format()
메서드입니다. 이 메서드는 f-strings보다 더 장황하지만, 가끔 장점이 있습니다(아래 세부사항 참조).
마지막으로, %
-스타일 포맷팅을 레거시 코드에서 접할 수 있습니다.
f-strings 사용하기 (Python 3.6+)
f-strings (형식화된 문자열 리터럴)은 Python에서 문자열을 포맷하는 강력하고 간결한 방법입니다. 이들은 Python 3.6에서 도입되었으며, 변수, 표현식 및 함수 호출을 문자열에 직접 삽입하는 읽기 쉽고 효율적인 방법을 제공합니다.
f-string의 기본 구문에 대한 간단한 예는 다음과 같습니다.
name = 'Mark' output_string = f'My name is {name}.' print(output_string)
My name is Mark.
이 코드에서 output_string
변수는 f-string에 할당됩니다. f
로 시작하는 접두사는 문자열이 내장 표현식을 지원함을 나타냅니다. 변수 name
은 평가되어 그 값이 문자열에 삽입되어 출력 결과는 다음과 같습니다: "내 이름은 마크입니다."
변수 값뿐만 아니라 계산이나 표현식도 f-string에 삽입될 수 있습니다. 이 예를 고려해 보세요.
import math a = 3.0 b = 4.0 # 수식을 위한 문자열 보간 사용 print(f'The hypotenuse of a triangle with base {a} and side {b} is {math.sqrt(a ** 2 + b ** 2)}.')
The hypotenuse of a triangle with base 3.0 and side 4.0 is 5.0.
표현식 math.sqrt(a ** 2 + b ** 2)
는 문자열 내에서 직접 평가되어, 값을 별도로 계산한 후 문자열에 삽입할 필요가 없습니다.
.format() 메서드 사용하기
f-스트링과 마찬가지로, .format()
메서드는 변수와 표현식을 문자열에 삽입할 수 있게 해줍니다. .format()
메서드의 기본 구문은 다음과 같습니다.
name = 'Mark' output_string = 'My name is {}.'.format(name) print(output_string)
My name is Mark.
중괄호 {}
는 자리 표시자로 사용되어, 해당 위치에 변수의 값이 문자열에 삽입될 것임을 나타냅니다. 자리 표시자에 삽입되는 특정 변수의 값은 .format()
메서드에 제공된 인수에 의해 결정됩니다.
위치 인수
여러 변수에 대해 여러 자리 표시자가 필요한 경우에는 어떻게 될까요? 다음 코드를 고려해 보세요.
name = 'Mark' age = 7 # 자리 표시자는 인수의 순서에 따라 채워집니다 output_string = 'My name is {} and I am {} years old.'.format(name, age) print(output_string)
My name is Mark and I am 7 years old.
이 예제에서는 두 개의 변수, name
와 age
가 필요합니다. 따라서 문자열에는 두 개의 자리 표시자가 포함되어 있으며, 변수는 .format()
메서드에 나타나는 순서대로 삽입됩니다. 이러한 인자는 *위치 인자*로 알려져 있으며, 문자열에서의 위치는 메서드의 인자 목록에서의 위치에 의해 결정됩니다.
인덱스 및 이름이 있는 자리 표시자
자리 표시자 아이디어의 변형으로, 이 예제를 고려해 보세요.
name = 'Mark' age = 7 # 나이를 두 번 출력하기 output_string = 'My name is {} and I am {} years old. My twin brother is also {} years old.'.format(name, age, age) print(output_string)
My name is Mark and I am 7 years old. My twin brother is also 7 years old.
여기에서 우리는 변수 age
의 값을 두 번 재사용했습니다. 이렇게 같은 변수를 여러 번 포함하는 것은 번거롭고 가독성을 떨어뜨립니다. 반복하지 않고 .format()
메서드로 형식화된 문자열에서 변수를 재사용하는 방법이 있을까요? 네, 있습니다. 소위 *인덱스 플레이스홀더*를 사용하면 됩니다.
name = 'Mark' age = 7 # 인덱스 플레이스홀더 사용하기 output_string = 'My name is {0} and I am {1} years old. My twin brother is also {1} years old.'.format(name, age) print(output_string)
My name is Mark and I am 7 years old. My twin brother is also 7 years old.
이 예제에서는 중괄호 내에서 변수의 순서를 명시적으로 정의했으며, 파이썬의 0 기반 인덱싱을 따릅니다. 또한 우리는 변수를 반복하는 대신 인덱스 1에서 재사용했습니다.
위치 인덱싱의 대안으로, 각 인수를 이름으로 지정하는 명명된 인수를 사용할 수도 있습니다.
print('My name is {name} and I am {age} years old.'.format(name='Mark', age=7))
My name is Mark and I am 7 years old.
이름 있는 인수는 그 이름을 지정하는 중괄호 내에서 평가됩니다. 결과적으로 {name}
자리 표시자는 "Mark"
로 대체되고, {age}
자리 표시자는 30
로 대체됩니다.
% 연산자 사용하기
문자열 보간의 마지막 방법은 %
연산자입니다. 이는 C의 printf()
명령과 유사하게 작동합니다. f-문자열이나 .format()
메서드를 사용하는 것이 권장되므로 이 사용은 더 이상 권장되지 않으며 강력히 지양됩니다. 레거시 코드베이스에서 이를 접할 수 있기 때문에 여기에서 언급됩니다.
%%
연산자의 기본 형식은: "형식 문자열" % 값
입니다. 형식 문자열에는 값으로 대체되는 자리 표시자가 포함되어 있습니다. 예를 들어, 다음 예는 “안녕하세요, 마크.”를 출력합니다.
'Hello %s' % 'Mark'
'Hello Mark'
다음 표에는 다른 일반적인 형식 지정자가 표시됩니다.
지정자 |
의미 |
예 |
---|---|---|
%s |
문자열 |
“안녕하세요 %s” % “앨리스” → “안녕하세요 앨리스” |
%d |
정수 (10진수) |
“나이: %d” % 25 → “나이: 25” |
%f |
부동 소수점 (기본 6자리) |
“파이: %f” % 3.14159 → “파이: 3.141590” |
%.nf |
부동 소수점 (n 자리) |
“%.2f” % 3.14159 → “3.14” |
%x |
16진수 (소문자) |
“%x” % 255 → “ff” |
%X |
16진수 (대문자) |
“%X” % 255 → “FF” |
%o |
8진수 |
“%o” % 255 → “377” |
% 연산자는 많은 제한이 있습니다. 우선, f-문자열보다 가독성이 떨어집니다. 다음 코드를 고려해 보세요.
name = "Alice" age = 30 height = 5.6 # % 연산자는 스캔하기 어렵습니다 message = "My name is %s, I am %d years old, and my height is %.1f feet." % (name, age, height) print(message)
My name is Alice, I am 30 years old, and my height is 5.6 feet.
이 코드가 한눈에 명확한가요? 아마도 아닐 것입니다. 자리 표시자와 빈칸을 채우는 변수 간의 시각적 파싱이 많이 발생합니다. 이처럼 계속 왔다 갔다 하다 보면 혼란스러워지기 쉽습니다.
이제 f-문자열을 사용한 동등한 코드를 고려해 보겠습니다.
# 이것은 훨씬 깔끔합니다 message = f"My name is {name}, I am {age} years old, and my height is {height:.1f} feet." print(message)
My name is Alice, I am 30 years old, and my height is 5.6 feet.
스캔할 필요도 없고 불분명한 포맷 문자열도 필요하지 않습니다. 코드는 깔끔하고 이해하기 쉬우며 작성하기도 쉽습니다. DataCamp의 Python 프로그래밍 스킬 트랙을 통해 명확하고 최적화된 코드를 작성하는 다른 팁을 배울 수 있습니다.
고급 파이썬 문자열 보간 기법
이제 파이썬 문자열 보간의 기본을 이해했으니, 좀 더 고급 사용법을 살펴보겠습니다.
파이썬 다중 행 문자열 보간
f-문자열은 삼중 따옴표(단일 또는 이중)를 사용하여 다중 행 콘텐츠에도 사용할 수 있습니다. 텍스트는 여러 줄에 걸쳐 작성할 수 있으며, 출력에서는 포맷된 대로 정확하게 나타납니다.
name = 'Mark' profession = 'Astronaut' age = 7 # 이것은 다중 행 문자열의 예입니다 bio = f""" Name: {name} Profession: {profession} Age: {age} """ print(bio)
Name: Mark Profession: Astronaut Age: 7
멀티라인 문자열은 .format()
메서드를 사용하여 생성할 수도 있습니다.
name = 'Mark' profession = 'Astronaut' age = 7 # 이것은 .format()을 사용하는 멀티라인 문자열입니다. bio = """ Name: {} Profession: {} Age: {} """.format(name, profession, age) print(bio)
Name: Mark Profession: Astronaut Age: 7
멀티라인 문자열 보간의 사용 사례
멀티라인 문자열 보간을 사용하려는 이유는 무엇일까요? 멀티라인 문자열 보간에는 많은 용도가 있습니다. 다음은 몇 가지 사용 사례입니다:
- 멀티라인 이메일 또는 메시지 생성
- 로그 및 디버깅
- SQL 쿼리 동적 생성
멀티라인 이메일 또는 메시지 생성
기술 컨퍼런스에 여러 초대자에게 양식 편지를 보내고 있다고 가정해봅시다.
name = "Alice" event = "Annual Tech Conference" date = "March 15, 2025" email = """Dear {name}, We are pleased to invite you to the {event} taking place on {date}. We hope you can join us for an exciting experience. Best regards, The Event Team""".format(name=name, event=event, date=date) print(email)
Dear Alice, We are pleased to invite you to the Annual Tech Conference taking place on March 15, 2025. We hope you can join us for an exciting experience. Best regards, The Event Team
f-스트링을 사용하면 양식 편지를 간단하고 효율적으로 만들 수 있습니다. 이름, 이벤트 또는 날짜를 변경하려면 변수에서 간단히 변경하면 문자열이 자동으로 변경됩니다.
로그 및 디버깅
멀티라인 문자열은 로그에 오류 메시지를 출력하는 데 유용합니다.
error_code = 404 url = '/missing-page' timestamp = '2025-02-05 12:30:00' error_message = 'The requested page could not be found.' log_message = f"""[ERROR {error_code}] Time: {timestamp} URL: {url} {error_message}""" print(log_message)
[ERROR 404] Time: 2025-02-05 12:30:00 URL: /missing-page The requested page could not be found.
이 방법은 로그 메시지를 구조화된 형태로 유지하며, 적절하게 형식화된 로그로 디버깅을 쉽게 만듭니다.
SQL 쿼리 동적 생성
SQL 쿼리는 멀티라인 문자열을 사용하여 동적으로 구축할 수 있습니다.
table = 'users' column = 'email' value = '[email protected]' query = f"""SELECT * FROM {table} WHERE {column} = '{value}';""" print(query)
SELECT * FROM users WHERE email = '[email protected]';
이 방법은 SQL 쿼리를 읽기 쉽게 만들고 들여쓰기를 유지합니다. 또한, 문자열 연결을 위해 +
를 사용할 필요가 없습니다.
기타 사용 사례는 다음과 같습니다:
- 서식이 지정된 계약서 작성
- Markdown 또는 $\LaTeX$ 문서 생성
- 다중 행 HTML/XML 템플릿
- API 응답 또는 JSON과 유사한 텍스트 생성
다중 줄 문자열 보간의 장점
보시다시피, 다중 줄 문자열 보간에는 여러 가지 장점이 있습니다.
- 문자열 보간은 이스케이프 문자
\n
없이 형식을 유지합니다. - 문자열 보간은 단일 줄 형식에 비해 가독성을 향상시킵니다.
- 문자열 보간은 구조화된 텍스트(예: 로그, 쿼리, 보고서)를 다룰 때 혼잡을 줄입니다.
- 문자열 보간을 사용하면 들여쓰기를 깨지 않고 동적인 텍스트 생성을 할 수 있습니다.
숫자 및 특수 값 포맷팅
f-string을 사용하여 표시할 소수점 이하 자리수를 제어하려면 다음 구문을 사용합니다: f'{value:.nf}'
, 여기서 value
는 부동 소수점 숫자, n
은 소수점 이하 자리수, f
(.
뒤의 것)이 부동 소수점 포맷팅을 의미합니다.
예를 들어, 다음 코드는 $\pi$를 서로 다른 소수점 자리수로 출력합니다.
pi = 3.1415926535 print(f'Pi rounded to 2 decimal places: {pi:.2f}') print(f'Pi rounded to 4 decimal places: {pi:.4f}') print(f'Pi rounded to 0 decimal places: {pi:.0f}')
Pi rounded to 2 decimal places: 3.14 Pi rounded to 4 decimal places: 3.1416 Pi rounded to 0 decimal places: 3
.format()
메서드를 사용한 포맷팅은 비슷합니다.
print('Pi rounded to 2 decimal places: {:.2f}'.format(pi)) print('Pi rounded to 4 decimal places: {:.4f}'.format(pi)) print('Pi rounded to 0 decimal places: {:.0f}'.format(pi))
Pi rounded to 2 decimal places: 3.14 Pi rounded to 4 decimal places: 3.1416 Pi rounded to 0 decimal places: 3
f-string을 사용하여 백분율을 포맷하려면 :.nf
구문과 %
를 조합하여 사용할 수 있습니다. 여기서 n
은 소수점 자리수입니다.
score = 0.875 print(f"Success rate: {score:.2%}")
Success rate: 87.50%
f-스트링을 사용하여 통화를 포맷할 수 있습니다. :,
는 천 단위 구분 기호로 사용되고 .nf
는 소수 자릿수를 조절합니다. 또한 문자열 안에 $ , € 또는 £와 같은 통화 기호를 직접 포함할 수 있습니다.
amount = 98765.4321 print(f"USD: ${amount:,.2f}") print(f"EUR: €{amount:,.2f}") print(f"GBP: £{amount:,.2f}")
USD: $98,765.43 EUR: €98,765.43 GBP: £98,765.43
딕셔너리 및 리스트와 함께 f-스트링 사용하기
Python에서 딕셔너리와 함께 f-스트링을 사용하려면 중괄호 안에서 대괄호 표기법 (dict[‘key’])를 사용하여 딕셔너리 값을 접근하거나 **로 딕셔너리를 언팩할 수 있습니다.
person = { 'name': 'Alice', 'age': 30, 'city': 'New York' } print(f"My name is {person['name']}, I am {person['age']} years old, and I live in {person['city']}.")
My name is Alice, I am 30 years old, and I live in New York.
각 키에 수동으로 접근하는 대신 다음과 같이 f-스트링으로 딕셔너리를 언팩할 수 있습니다.
person = { 'name': 'Alice', 'age': 30, } print(f'My name is {name} and I am {age} years old.'.format(**person))
My name is Alice and I am 7 years old.
누락된 키로 인한 오류를 피하려면 get()
를 사용하여 딕셔너리에 접근하세요.
person = {"name": "Alice"} # 오류: 'city' 키가 누락되었습니다 print(f"City: {person['city']}")
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[87], line 4 1 person = {"name": "Alice"} 3 # 오류: 'city' 키가 누락되었습니다 ----> 4 print(f"City: {person['city']}") KeyError: 'city'
print(f"City: {person.get('city', 'Not specified')}")
City: Not specified
문자열 보간 방법의 장단점
우리가 보았듯이, f-문자열과 .format()
메서드는 문자열 보간을 위한 유용한 방법입니다. 각 방법의 장단점을 비교해 보겠습니다.
특징 |
f-문자열 |
.format() |
% 포맷팅 |
---|---|---|---|
가독성 |
🟢 최고 |
🟡 괜찮음 |
🔴 더 어려움 |
성능 |
🟢 가장 빠름 |
🟡 느림 |
🔴 가장 느림 |
표현식 지원 |
🟢 예 |
🟡 간접적 |
🔴 아니오 |
다중 행 지원 |
🟢 예 |
🟢 예 |
🔴 아니오 |
사용 용이성 |
🟢 가장 쉬움 |
🟡 보통 |
🔴 어려움 |
디버깅 (= 연산자) |
🟢 예 (Python 3.8+) |
🔴 아니오 |
🔴 아니오 |
언제 .format()
을 f-strings 대신 사용해야 하나요?
장점 |
.format() 사용 이유 |
---|---|
레거시 파이썬 지원 |
Python 2.7+에서 작동 |
유연한 순서 지정 |
플레이스홀더의 재정렬을 쉽게 허용 |
동적 포맷팅 |
포맷 지정자가 동적일 때 작동 |
{} 중괄호를 더 잘 처리 |
추가 수동 이스케이프를 피함 |
딕셔너리와 잘 작동 |
딕트 키를 더 쉽게 사용 |
일반적인 함정과 모범 사례
아래에서 파이썬 문자열 보간을 사용할 때의 몇 가지 문제 해결 방법과 주요 팁을 찾을 수 있습니다.
중괄호로 인한 구문 오류 피하기
중괄호를 포함한 문자열 보간을 사용할 때 발생할 수 있는 많은 구문 오류가 있습니다.
- 모든 {가 일치하는 }가 있는지 확인하세요.
print('Hello, my name is {name!'}
Cell In[96], line 1 print('Hello, my name is {name!'} ^ SyntaxError: closing parenthesis '}' does not match opening parenthesis '('
다행히도 오류는 간단하며 수정하기 쉽습니다.
- 리터럴 {}를 표시하려면 {{ 및 }}를 사용하세요.
보간된 문자열 안에 중괄호를 출력하고 싶다면 어떻게 될까요? 중괄호 안의 모든 것은 (평가를) 시도할 것입니다.
print(f'Set notation: {a, b, c}')
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[101], line 1 ----> 1 print(f'Set notation: {a, b, c}') NameError: name 'c' is not defined
Python은 중괄호 안의 a, b, c를 튜플로 해석하고 a와 관련된 값을 찾으려고 시도합니다. 그러한 변수가 존재하지 않기 때문에 KeyError가 발생합니다. 수정 방법은 이중 중괄호를 사용하는 것입니다 {{}}
.
print("Set notation: {{a, b, c}}")
집합 표기법: {{a, b, c}}
성능 비교: f-strings 대 .format()
f-strings와 .format()
의 성능을 비교해 봅시다..
import timeit name = "Alice" age = 30 pi = 3.1415926535 # f-string 성능 측정 f_string_time = timeit.timeit('f"My name is {name} and I am {age} years old."', globals=globals(), number=1000000) # .format() 성능 측정 format_time = timeit.timeit('"My name is {} and I am {} years old.".format(name, age)', globals=globals(), number=1000000) # 표현식을 사용한 f-string 성능 측정 f_string_expr_time = timeit.timeit('f"Pi rounded to 2 decimal places: {pi:.2f}"', globals=globals(), number=1000000) # 표현식을 사용한 .format() 성능 측정 format_expr_time = timeit.timeit('"Pi rounded to 2 decimal places: {:.2f}".format(pi)', globals=globals(), number=1000000) # 결과 출력 print(f"f-string (simple): {f_string_time:.6f} seconds") print(f".format() (simple): {format_time:.6f} seconds") print(f"f-string (with expression): {f_string_expr_time:.6f} seconds") print(f".format() (with expression): {format_expr_time:.6f} seconds")
f-string (simple): 0.080447 seconds .format() (simple): 0.129860 seconds f-string (with expression): 0.123171 seconds .format() (with expression): 0.146242 seconds
효율성 측면에서, f-string이 .format()
보다 선호되어야 함을 알 수 있습니다.
깨끗하고 읽기 쉬운 문자열 보간을 위한 모범 사례
문자열 포맷팅이 명확하고 효율적이며 유지 관리 가능하도록 하기 위해, 보간된 문자열을 사용할 때 다음 모범 사례를 따르세요.
- 가독성을 위해 f-string을 선호하세요 (Python 3.6 이상)
# 추천 name = "Alice" age = 30 print(f"My name is {name} and I am {age} years old.") # 비추천 (가독성이 떨어짐) print("My name is {} and I am {} years old.".format(name, age)) # % 포맷팅 사용 피하기 (구식) print("My name is %s and I am %d years old." % (name, age))
My name is Alice and I am 30 years old. My name is Alice and I am 30 years old. My name is Alice and I am 30 years old.
- 명확성을 위해 이름 있는 플레이스홀더 사용
# 명명된 자리 표시자 (읽기 쉬움) user = {"name": "Alice", "age": 30} print(f"My name is {user['name']} and I am {user['age']} years old.") # .format()에서 인덱스 사용 (읽기 어려움) print("My name is {0} and I am {1} years old.".format("Alice", 30))
My name is Alice and I am 30 years old. My name is Alice and I am 30 years old.
- 다중 행 문자열을 읽기 쉽게 유지하십시오.
name = "Alice" age = 30 message = f"""Hello, {name}! We are happy to invite you to our event. At {age} years old, you are eligible for the VIP pass. Best regards, Event Team """ print(message)
Hello, Alice! We are happy to invite you to our event. At 30 years old, you are eligible for the VIP pass. Best regards, Event Team
- 로깅에서 더 나은 디버깅을 위해 f-문자열 사용
Python 3.8 이상에서는 f-문자열에서 디버깅을 위한 =
을 지원합니다.
value = 42 # Output: value = 42 print(f"{value = }")
value = 42
결론
문자열 보간은 Python에서 강력한 기능으로, 문자열 형식을 더 깔끔하고 읽기 쉽고 효율적으로 만듭니다. 사용 가능한 방법 중에서 f-문자열은 가장 현대적이며 권장되는 접근 방식으로, .format()
및 %
형식과 같은 이전 방법보다 더 나은 성능, 명확성 및 유연성을 제공합니다.
이름이 지정된 자리 표시자를 사용하고, 소수 자릿수를 제어하며, 가독성을 위해 텍스트를 정렬하고, 누락된 사전 키를 우아하게 처리하는 등의 모범 사례를 따르면, Python에서 깔끔하고 전문적이며 유지 관리가 쉬운 문자열 포맷팅을 작성할 수 있습니다.
형식이 지정된 보고서, 다중 행 메시지 또는 구조화된 데이터 출력을 생성하든, f-문자열은 변수와 표현식을 매끄럽게 통합하는 간단하면서도 강력한 방법을 제공합니다. f-문자열을 수용하면 코드 품질이 향상될 뿐만 아니라 효율성도 높아집니다.
Python 문자열 보간에 대한 추가 정보는 DataCamp의 리소스를 확인하세요:
- 파이썬의 f-string 포맷팅 튜토리얼
- 파이썬 문자열 추가: 6가지 필수 연결 기법
- 파이썬 프로그래밍 기술 트랙
- 파이썬 기초 기술 트랙
- 파이썬 데이터 과학 입문 과정
Source:
https://www.datacamp.com/tutorial/python-string-interpolation