파이썬에서 문자열 포맷팅 방식은 다양합니다. 아래에서 다양한 방법과 사용법을 설명하겠습니다.

% 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 "<stdin>", line 1, in <module>
TypeError: %i format: a number is required, not str

왜 좋지 않다고 할까?

바로 위에서 설명한 것과 같이 타입을 정확하게 알고 사용해야 한다는 단점도 있지만 포맷팅할 문자열이 길어지면 곧바로 더러워지는 것을 볼 수 있습니다.

first_name = 'Eric'
last_name = 'Idle'
age = 74
profession = 'comedian'
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)
# Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.

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))

# Hello, Eric Idle. You are 74. You are a comedian. You were a member of Monty Python.


.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 선언을 먼저 한 후, 변수를 나중에 선언하는 형식 또한 가능합니다.

test = f'Hi {name}'
name = 'Bob'
print(test)


# Hi Bob

속도

아래 예시와 같이 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

>>> timeit.timeit("""name = "Eric"
... age = 74
... '{} is {}.'.format(name, age)""", number = 10000)
0.004242089427570761

f-string

>>> timeit.timeit("""name = "Eric"
... age = 74
... f'{name} is {age}.'""", number = 10000)
0.0024820892040722242


+ Random Posts