파이썬 코드에는 문자열을 많이 쓴다.
사용자 인터페이스 또는 명령줄 유틸리티에 메시지 표시
파일과 소켓에 데이터를 쓰기
잘못된 일 발생 시, Exception에 자세히 기록할 때 컴프리헨션을 이용해서 문자열 사용
디버깅 발생 시, 대화형 혹은 repr문자열 사용
미리 정의된 문자열에 데이터 값을 끼워서 보기 좋게 문자열을 저장하는 과정
언어에 내장된 기능과 표준 라이브러를 통해 네 가지 방식으로 형식화
형식 문자열
탬플릿에 끼워 넣을 값들은 연산자의 오른쪽에 단일 값 혹은 tuple 지정
연산자 왼쪽에 있는 값을 끼워 넣을 자리르 표현하기 위해 형식 지정자 사용
a = 0b10111011
b = 0xc5f
print('이진수: %d, 십육진수: %d' % (a,b))
#이진수: 187, 십육진수: 3167
형식 지정자의 문법
파이썬에서 C 스타일 형식 문자열 사용 시 4가지 문제점
즉, 오른쪽에 있는 파라미터의 순서를 그대로 유지하고 형식 문자열의 순서를 바꿔도 같은 오류 발생
key = 'my_var'
value = 1.234
formatted = '%-10ss = %2.f' % (key, value)
print(formatted) # my_var = 1.23
형식화 전에 값을 살짝 변경해야 하면 식을 읽기가 매우 어려워짐
형식화 문자열에서 같은 값을 여러 번 사용 시 튜플에서 같은 값을 여러 번 반복해야하는 점입니다.
해결법
파이썬의 % 연산자에는 튜플이 아닌 딕셔너리 사용하여 형식화 기능
딕셔너리의 키는 형식 지정자의 키와 매치된다.(ex:%(key)s)
출력에 영향을 주지 않고 값의 순서 바뀌기 가능(첫 번째 문제 해결)
형식화 식에 딕셔너리 사용 시 여러 형식 지정자에 같은 키를 지정할 수 있게 되어서 같은 값을 반복하지 않게 되어 세 번째 문제 해결
*첫 번째 문제 해결
key = 'may_var'
value = 1.234
old_way = '%-10s = %.2f' % (key,value)
new_way = '%(key)-10s = %(value).2f' % {
'key': key, 'value': value}# 원래 방식
reordered = '%(key)-10s = %(value).2f' % {
'value': value, 'key': key} # 바뀐 방식
assert old_way == new_way == reordered
*세 번째 문제 해결
name = '철수'
template = '%s는 음식을 좋아해. %s가 요리하는 모습을 봐요.'
before = template % (name, name) #튜플
template = '%(name)s는 음식을 좋아해. %(name)s가 요리하는 모습을 봐여.'
after = template % {'name':name} #딕셔너리
asserf before =- after
딕셔너리 형식 문자열을 사용하면 다른 문제가 더 심해지거나 새로운 문제 생김
for i, (item, count) in enumerate(pantry):
before = '#%d: %-10s = %d' % (
i + 1,
item.title(),
round(count))
after = '#%(loop)d: %(item)-10s = %(count)d' % {
'loop': i + 1,
'item': item.title(),
'count': round(count),
}
assert before == after
고급 문자열 형식화
a = 1234.5678
formatted = format(a, ',.2f')
print(formatted) #1,234.57
b = 'my 문자열'
formatted = for(b, '^20s')
print(formatted) #* my 문자열 *
str타입에 새로 추가된 format메서드를 호출하면 여러 값에 대해 기능 적용
key = 'my_var'
value = 1.234
formatted = '{} ={}'.format(key,value)
print(formatted) # my_var = 1.234
#위치 지정자 적용
formatted = '{:<10} = {:2.f}'.format(key,value)
print(formatted) # my_var = 1.23
# 그 위치에 해당하는 값: 뒤에 있는 형식 지정자를 FORMAT 내장 함수에 전달해 얻은 결과와 같다.
# 형식화된 전체 문ㅁ자열의 해당 위치 지정자 부분 대신
# 특별 메서드인 __format__을 사용해서 클래스별 형식화 방식으로 커스텀화
C 스타일 형식화 문자열에서 %문자 표시
print('%.2f%%' % 12.5) # 12.50%
print('{} replaces {{}}'.format(1.23)) # 1.23 replaces {}
*C 스타일 첫 번째 문제 해결
format 메서드(위치 지정자 중괄호에 위치 인덱스)에 전달된 인자의 순서를 표현하는 위치 인덱스 전달
순서를 바꾸지 않고 형식화 문자열 사용해서 형식화한 값의 출력 순서 변경 가능
formatted = '{1} = {0}'.format(key, value)
print(formatted) #12.34 = my_var
*C 스타일 세 번째 문제 해결
형식화 문자열 안에서 같은 위치 인덱스 여러 번 사용 가능
format에 넘기는 인자에 값을 여러 번 반복 필요 없음
formatted = '{0}는 음식을 좋아해. {0}가 요리하는 모습을 봐요.'.format(name)
print(formatted) #철수는 음식을 좋아해. 철수가 요리하는 모습을 봐요
*C 스타일 두 번째 문제 해결 불가
*C 스타일 네 번째 문제 해결 불가(키의 반복성 해결 불가)
str.format와 함께 사용하는 형식 지정자
formatted = '첫 번째 글자는 {menu[oyster][0]!r}'.format(
menu=menu)
print(formatted) #첫 번째 글자는 't'
형식 문자열 앞에는 f문자를 붙인다
바이트 문자열 앞에는 b문자를 붙인다
raw문자열(이스케이프x) 앞에는 r문자를 붙인다.
형식 문자열의 표현력 극대화
키와 값을 불필요하게 중복 지정하는 경우 해결(C스타일 4번째 해결)
형식화 식 안에서 파이썬 영역에서 사용할 수 있도록 모든 이름을 자유롭게 참조하도록 허용이 가능하는 간결함이 됩니다.
key = 'my_var'
value = 1.234
formatted = f'{key} = {value}'
print(formatted) # my_var = 1.234
#format 함수의 형식 지정자 안에서 콜론 뒤에 사용이 가능한 내장 미니 언어 사용 가능
# 값을 유니코드나 repr문자열로 변환하는 기능 사용
formatted = f'{key!r:<10} = {value:.2f}'
print(formatted) #my_var = 1.23
f_string = f'{key:<10} = {value:.2f}'
c_tuple = '%-10s = %.2f' % (key, value)
str_args = '{:<10} = {:.2f}'.format(key=key,
value = value)
c_dict = '%(key)-10s = %(value).2f' % {'key':key
'value':value}
assert c_tuple == c_dict == f_string
assert str_args == str_kw == f_string
간결한 구문으로 표기가 가능하다(C스타일 두 번째 문제 해결)
for i, (item, count) in enumerate(pantry):
print(f'#{i+1}: '
f'{item.title():<10s} = '
f'(round(count)}')
#1:아포카도 = 1
#2:바나나 = 2
#3:체리 = 15
파이썬 식을 형식 지정자 옵션에 넣기 가능
places = 3
number = 1.23456
print(f'내가 고른 숫자는 {number:.{places}f}') #내가 고른 숫자는 1.235
%연산자를 사용하는 C 스타일 형식화 문자열은 여러 가지 단점 및 번잡성이라는 문제가 있다.
str.format 메서드
f-문자열은 값을 문자열 안에 넣는 새로운 구문으로, C스타일 형식화 문자열의 가장 큰 문제점 해결
f-문자열은 간결하지만, 위치 지정자 안에 임의의 파이썬 식을 직접 포함 가능
f-문자열은 표현력, 간결성, 명확성 제공하기 가장 좋다.
값을 문자열로 형식화 해야한다면 f-문자열을 사용해라