-
[Python] 문자열 포맷팅 방법들 (%, str.format, f-string)언어/파이썬 & 장고 2019. 1. 20. 04:04
파이썬에서 문자열 포맷팅 방식은 다양합니다. 아래에서 다양한 방법과 사용법을 설명하겠습니다.
% operator (오래된 방식)
C에서 prinf 스타일로 사용한 적이 있으면 익숙한 방식입니다. python3 이전의 방식으로 편리하지만 타입을 정확하게 알고 작성해야 한다는 단점이 있습니다.
test = 'Hello %s' % 'Bob' print(test) # Hello Bob
만약 데이터 타입이 integer일 경우 아래와 같이 %s로 추가합니다.
test = 'age: %i' % 111 print(test) # age: 111
만약 포맷팅하고자 하는 데이터 타입이 다를 경우, 아래와 같이 에러를 뱉게 됩니다.
test = 'age: %i' % '111' # Traceback (most recent call last): File "", line 1, in <module> TypeError: %i format: a number is required, not str
왜 좋지 않다고 할까?
바로 위에서 설명한 것과 같이 타입을 정확하게 알고 사용해야 한다는 단점도 있지만 포맷팅할 문자열이 길어지면 곧바로 더러워지는 것을 볼 수 있습니다.
first_name = 'Eric' last_name = 'Idle' age = 74 profession = 'comedian' affiliation = 'ttt' affiliation = 'Monty Python' 'Hello, %s %s. You are %s. You are a %s. You were a member of %s.' % (first_name, last_name, age, profession, affiliation)
str.format
파이썬3 이후부터 새로운 포맷팅을 제시합니다.
test = 'Hello {}'.format('Bob') print(test) # Hello Bob
파이썬3 에서도 % operator를 지원하지만 공식문서에서는 권장하지 않는다고 나와 있습니다. (새로나온 str.format이 너무 좋아서..)
format 메소드는 아래와 같이 여러 형태로 지원됩니다.
test = 'Hello {name}. count: {count}' test.format(name='Bob', count=5) # 'Hello Bob. count: 5'
test = 'Hello {1}. count: {0}' test.format(10, 'Jim') # 'Hello Jim. count: 10'
왜 좋지 않을까?
% operator보다는 읽기 좋지만 여러 매개변수와 긴 문자열을 처리할 때 장황하다는 것을 확인할 수 있습니다.
first_name = 'Eric' last_name = 'Idle' age = 74 profession = 'comedian' affiliation = 'Monty Python' print(('Hello, {first_name} {last_name}. You are {age}. ' + 'You are a {profession}. You were a member of {affiliation}.').format(first_name=first_name, last_name=last_name, age=age, profession=profession, affiliation=affiliation))
.format()에 전달할 변수가 길다면 dictionary 형태로 담아서 .format(**some_dict)로 압축해서 전달할 수 있습니다. 파이썬 3.6이상에서는 이러한 문제를 해결하기 위해 좀 더 직관적인 방법을 제시합니다.
f-string
f-string은 파이썬 3.6 이상 버전에서만 지원하는 문법입니다. str.format이 % operator에 비해 강력하고 사용하기 쉽지만 f-string은 더욱더 간편해졌습니다.
name = 'Bob' test = f'Hello {name}' print(test) # Hello Bob
str.format과 다르게 정수끼리의 산술 연산도 지원합니다.
a = 2 b = 3 test = f'sum: {a + b}' print(test) # sum: 5
속도
아래 예시와 같이 f-string이 가장 빠른 것으로 확인할 수 있습니다. f-striing은 상수 값이 아닌 런타임에서 계산이 되는 표현식입니다. https://www.python.org/dev/peps/pep-0498/#abstract에서 f-string에 대한 자세한 내용을 확인할 수 있습니다.
% operator
import timeit timeit.timeit("""name = "Eric" ... age = 74 ... '%s is %s.' % (name, age)""", number = 10000) # 0.003324444866599663
str.format
import timeit timeit.timeit("""name = "Eric" ... age = 74 ... '{} is {}.'.format(name, age)""", number = 10000) # 0.004242089427570761
f-string
import timeit timeit.timeit("""name = "Eric" ... age = 74 ... f'{name} is {age}.'""", number = 10000) # 0.0024820892040722242