파이썬다운 코드를 작성하는 법

Heebeom·2023년 3월 12일
0

range()보다는 enumerate()

# 나쁜 예
animals = ['cat', 'dog', 'mouse']
for i in range(len(animals)):
	print(i, animals[i])
    
# 좋은 예
animals = ['cat', 'dog', 'mouse']
for index, animal in enumerate(animals):
	print(index, animal)

당신은 파이썬 리스트를 반복할 때 어떻게 사용하는가? 대부분 range()와 len() 함수를 사용해 반복하지만, 이는 읽기 어려우니 지양해야 한다.

enumerate() 함수를 사용하면 인덱스와, 리스트의 값을 같이 불러올 수 있다. range()와 len()을 사용하는 것 보다, 훨씬 깔끔한 파이썬다운 코드를 작성할 수 있다.

open(), close() 보다는 with 문을 사용하자

# 나쁜 예
try:
	file = open('spam.txt', 'w')
    eggs = 42 / 0 # 여기서 0 나누기 에러 발생
    file.close() # 이 행은 실행될 수 없음
except:
	print('에러 발생!')
    
# 좋은 예
with open('spam.txt', 'w') as file:
	file.write('Hello, world!')

파일을 열고 닫기 위해 open()과 close()를 따로 쓸 수 있지만, 이는 파이썬답지 않다. 중간에 에러 때문에 close() 호출을 건너뛸 수 있기 때문에, 파일 손상이 발생하기 쉽기 때문이다.

대신 with 문을 사용하면, with 블록을 벗어나면 자동으로 close() 호출하니 훨씬 파이썬스럽다.

==와 is는 다르다. 잘 사용하자.

동등 연산자 '=='는 두 개체의 값을, 동일 연산자 'is'는 아이디를 비교한다. 동일한 값을 가진 두 객체라도, 각각의 아이디는 다르다.

None는 넌타입 데이터의 유일한 값이기 때문에, None 객체는 단 하나밖에 없다. 그래서 is 연산자로 값을 비교해야 하며, '==' 연산자는 오버로딩 된 경우 잘못된 값을 반환할 수 있다. 이건 추후에 자세히 설명하겠다.

이와 반대로 부울(bool) 값은 is 연산자는 사용해서 안된다. 부울은 값이기 때문에 '==' 연산자를 사용해야 한다.

백슬래시가 많으면 원시 문자열을 사용하자

# 나쁜 예
print('C:\\Users\\Al\\Desktop\\Info\\Archive\\Spam')

# 좋은 예
print(r'C:\Users\Al\Desktop\Info\Archive\Spam')

파이썬의 '\'는 이스케이프 문자로 활용되며, 실제 백슬래시를 표현하기 위해 '\\'로 표기해야 한다. 이는 가독성이 매우 떨어지며, 파이썬 답지 않으니 원시 문자열을 사용하자.

원시 문자열은 r 접두사가 붙은 문자열 리터럴이며, 백슬래시를 이스케이프 문자로 취급하지 않는다.

f-String을 적극 사용하자.

# 나쁜 예
width, length = 10, 12
print(f'가로가 ' + width + ', 세로가 ' + length + '인 방은 ' + width * length + ' 면적을 가집니다.')

# 좋은 예
width, length = 10, 12
print(f'가로가 {width}, 세로가 {length}인 방은 {width * length} 면적을 가집니다.')

대부분 변수와 문자열을 결합할 때 '+' 연산자를 사용할 것이다. 위 예시를 보면 알겠지만, 이는 매우 보기 어려우며 특히 공백을 잘못 입력할 가능성이 크다.

다행히 파이썬 3.6 버전부터는 f-String이라는 아주 강력한 기능을 제공한다. f 접두사가 붙은 문자열을 생성하면, 중괄호 안 변수를 자동으로 문자열로 치환한다.

만약 중괄호를 출력하고 싶다면, 이중으로 중괄호를 작성하면 된다.

딕셔너리를 적극 활용하자.

# 나쁜 예
if season =='겨울':
	holiday = '크리스마스'
elif season == '봄':
	holiday = '삼일절'
elif season = '여름':
	holiday = '광복절'
elif season = '가을':
	holiday = '할로윈'

# 좋은 예
holidays = {'겨울': '크리스마스',
		   '봄': '삼일절',
           '여름': '광복절',
           '가을': '활로윈'}
           
print(holiday['가을']) # '할로윈'

파이썬은 특정 한 변수에 많은 값을 분기하는 switch 문이 없다. 그래서 여러 if-elif-else 문을 사용하는데, 이를 딕셔너리를 사용하면 간결한 코드를 만들 수 있다.

위 두 예시를 비교해 보자. 좋은 예가 훨씬 더 코드가 깔끔하고 파이썬스럽다. 하지만 딕셔너리의 key 값을 잘못 입력하면 KeyError가 발생하기 쉽다.

from collections import defaultdict

# 기본값이 0인 score 딕셔너리 생성
scores = defaultdict(int)
scores['A1'] += 1 # A1 키가 자동으로 1로 설정
print(scores['A1']) # 1 출력

만약에 점수 같이 기본값을 가지고 시작하는 경우는 collections.defaultdict을 사용하면 된다. 이러면 없는 key에 대해 자동으로 기본값을 생성해 줘서, KeyError에서 자유롭다.

체이닝 기능을 활용해보자.

# 나쁜 예
if 42 < spam and spam < 99:

# 좋은 예
if 42 < spam < 99:

숫자가 일정 범위 내에 있는지 확인해야 할 때, 대부분은 'and' 연산자를 활용한 위 나쁜 예시처럼 비교한다. 위 예시는 아무런 문제가 없지만, 파이썬스럽지는 않다.

파이썬은 비교 연산자에 체이닝 기능을 지원한다. 좋은 예처럼 굳이 하나의 조건만 비교할 필요가 없다.

조건 뿐만이 아니라 할당 연산자 '='도 체이닝이 된다. 만약 같은 값을 가지고 있다면, 체이닝을 활용해 깔끔하게 코드를 작성할 수 있다.

profile
이도저도 아닌 개발자

0개의 댓글