메서드 체이닝
1. 메서드 체이닝(Method Chaining)
메서드 체이닝이란 연속으로 메서드를 호출하는 것을 말합니다. 각 메서드는 결괏값이 있습니다. 이 결괏값에 메서드를 다시 호출하는 방식으로 연속적인 작업을 수행합니다.
메서드 체이닝은 코드를 간결하게 작성할 수 있지만, 과도하게 사용하면 가독성이 떨어지고 디버깅이 어려워집니다. 한 줄에 79자를 넘지 않도록 주의하세요.다만 너무 과하게 사용하면 가독성을 해칠 우려가 있으며 체이닝 설계가 제대로 되어 있지 않으면 오류가 날 수 있으니 적절하게 사용해주세요.
1.1 문자열의 메서드 체이닝
sentence = ' Hello, World! '
result = sentence.strip().lower().replace('world', 'python')
# 1번 스탭 : sentence.strip() == 'Hello, World!'
# 2번 스탭 : 'Hello, World!'.lower() == 'hello, world!'
# 3번 스탭 : 'hello, world!'.replace('world', 'python')
print(result) # 'hello, python!'
문자열을 처리할 때는 위처럼 여러 개의 메서드를 연속적으로 사용하는 경우가 많습니다. 위의 코드에서는 문자열의 양쪽 공백을 제거한 후, 소문자로 변경하고, 마지막으로 "world"를 "python"으로 치환했습니다.
한 단계씩 나누어 실행해보면 무슨 일이 벌어지는지 더 분명해집니다. 앞 메서드가 돌려준 값에 다음 메서드를 호출할 뿐입니다.
print(' Hello, World! '.strip()) # 'Hello, World!'
print('Hello, World!'.lower()) # 'hello, world!'
print('hello, world!'.replace('world', 'python')) # 'hello, python!'
아래와 같이 replace를 여러번 하는 것도 일반적으로 자주 사용되는 코드입니다.
' ,!! hello world '.replace(' ', '').replace(',', '').replace('!', '')
'helloworld'
다만 위와 같이 여러 개의 문자를 치환하거나, 삭제할 경우 문자열 메서드인 translate를 사용해주세요. 이보다 복잡도가 늘어나면 정규 표현식을 공부해야 합니다. 정규 표현식은 뒤 챕터에서 다루게 됩니다.
다른 언어처럼 개행을 해서 사용하고 싶다면 아래처럼 사용하시면 됩니다.
# 백슬래시를 사용해서 개행을 할 수 있습니다.
sentence = ' Hello, World! '
result = sentence\
.strip()\
.lower()\
.replace('world', 'python')
print(result) # 'hello, python!'
아래처럼 중간 공백을 허용합니다.
# 백슬래시를 사용해서 개행을 할 수 있습니다.
sentence = ' Hello, World! '
result = sentence\
.strip()\
.lower()\
.replace('world', 'python')
print(result) # 'hello, python!'
메서드 체이닝을 통해 한 줄이 79자 이상이 넘지 않도록 해주세요. PEP8는 한 줄에 79자를 넘지 않도록 권고합니다. colab에 보면 회색선이 그어져 있습니다. 여기까지가 79자 입니다.
1.2 반환값의 타입이 다음 메서드를 결정한다
메서드 체이닝에서 가장 중요한 것은 앞 메서드가 무엇을 돌려주는가입니다. 아래 코드는 제대로 작동하지 않습니다.
'010-1000-2000'.split('-').replace('0', 'x')
이는 아래의 순서로 진행이 됩니다.
split이 돌려준 값은 문자열이 아니라 리스트입니다. 즉 위 코드는 사실상 아래 코드와 같습니다.
['010', '1000', '2000'].replace('0', 'x')
리스트에는 replace라는 메서드가 없기 때문에 AttributeError가 발생합니다. 이처럼 앞에서부터 순서대로 메서드의 결괏값이 무엇이 나오는지 확인하고 그에 따른 올바른 메서드를 사용해야 합니다.
| 반환 타입 | 사용 가능한 메서드 예시 |
|---|---|
| 문자열(str) | replace, upper, lower, strip, split |
| 리스트(list) | append, pop, sort, reverse |
반환 타입이 헷갈릴 때는 중간에서 한 번 끊어 type()으로 확인해보세요.
x = '010-1000-2000'.split('-')
print(type(x)) # <class 'list'>
print(x)
리스트가 되었으니 그 다음에는 리스트가 할 수 있는 일을 시키면 됩니다. 처음부터 하려던 일이 문자열 치환이었다면 애초에 split을 거칠 필요가 없습니다.
'010-1000-2000'.replace('0', 'x')
만약 조각마다 따로 처리해야 한다면, 리스트를 되돌려받은 뒤 각 조각에 문자열 메서드를 적용해야 합니다.
[x.replace('0', 'x') for x in '010-1000-2000'.split('-')]