[BW 4] f-문자열을 통한 인터폴레이션

💡 형식화 : 미리 정의된 문자열에 데이터 값을 끼워 넣어서 사람이 보기 좋은 문자열로 저장하는 과정

 

% 형식화 연산자 사용과 문제점

a = 12345
b = 6789

print('a의 값: %d, b의 값: %d' % (a, b))

>>>
a의 값: 12345, b의 값: 6789

형식 지정자 : %s, %x, %f, %d 등을 말하며, 해당 위치에 지정한 문자를 형식화한다.

 

첫 번째 문제점

오른쪽에 있는 tuple 내 데이터의 순서를 바꾸거나 값의 타입을 바꾸면 오류가 발생할 수 있다.

key = "outer"
value = 8.23

miss_ordered_tuple = '%-10s = %.2f' % (value, key)

print(miss_ordered_tuple)

>>>
TypeError: must be real number, not str

두 번째 문제점

형식화를 하기 전에 값을 변경해야 한다면 식을 읽기가 매우 어려워질 수 있다.

# 수정 전
family = [
    ('아빠', 55),
    ('엄마', 54),
    ('동생', 26),
    ('아들', 7),
    ('짱구', 9)
]

for idx, (fam, age) in enumerate(family):
    print('#%d: %s의 나이는 %d 살' %(idx, fam, age))
# 수정 후
family = [
    ('아빠', 55),
    ('엄마', 54),
    ('동생', 26),
    ('아들', 7),
    ('짱구', 9)
]

for idx, (fam, age) in enumerate(family):
    print('#%d: %s의 나이는 %d 살' %(idx + 1, fam.title(), age))

→ 만약 바꿔야할 내용이 많다면 튜플이 길어져서 읽기 복잡해진다.

세 번째 문제점

형식화 문자열에서 같은 값을 여러 번 사용하고 싶다면 튜플에서 반복해야 한다.

# 수정 전
template = "%s는 음식을 좋아해. %s가 요리하는 모습을 봐요."
name = '짱구'
formatted = template % (name, name)

print(formatted)
# 수정 후
template = "%s는 음식을 좋아해. %s가 요리하는 모습을 봐요."
name = '짱구'
formatted = template % (name, name.title())

print(formatted)

→ 반복적으로 사용하다 보면 메서드 호출을 빼먹을 수 있다.

네 번째 문제점

첫 번째 문제점(순서 오류), 세 번째 문제점(반복으로 인한 실수)는 딕셔너리를 사용하면 해결할 수 있다.

key = "outer"
value = 8.23

new = '%(key)s = %(value).2f' % {
    'key' : key,
    'value' : value
}

print(new)

하지만 두 번째 문제점(가독성 저하)는 더 심각해진다.


내장 함수 format과 str.format

%d, %s와 같은 형식 지정자 대신 위치 지정자 {}를 사용한다.

key = "outer"
value = 8.23

formatted = '{}의 생일은 {}다.'.format(key, value)

print(formatted)

>>>
outer의 생일은 8.23다.

첫 번째 문제 해결(순서 오류)

위치 지정자 {} 안에 인덱스를 넣어 순서를 지정할 수 있다.

key = "outer"
value = 8.23

formatted = '{1}의 생일은 {0}다.'.format(value, key)

print(formatted)

>>>
outer의 생일은 8.23다.

세 번째 문제 해결(반복으로 인한 실수)

name = "수달"

formatted = '{0}은 음식을 좋아해. {0}이 연어를 먹는다.'.format(name)
print(formatted)

>>>
수달은 음식을 좋아해. 수달이 연어를 먹는다.

인터폴레이션을 통한 형식 문자열(f-문자열)

f-문자열은 형식 문자열의 표현력을 극대화하고, 네 번째 문제점(딕셔너리 사용으로 인한 가독성 저하)도 없애준다.

key = "outer"
value = 8.23

formatted = f'{key} = {value}'
print(formatted)

>>>
outer = 8.23

두 번째 문제점(가독성 저하)도 아래와 같이 해결할 수 있다.

family = [
    ('아빠', 55),
    ('엄마', 54),
    ('동생', 26),
    ('아들', 7),
    ('짱구', 9)
]

for idx, (fam, age) in enumerate(family):
    f_string = f'#{idx + 1}: {fam.title()}은(는) {age}살 이다.'
    print(f_string)

결론

f-문자열은 간결하고 강력하다.