가독성 좋은 파이썬 코드를 짜는 법 - PEP8에 대해서

Heebeom·2023년 3월 1일
1
post-thumbnail

개발자에게 가장 중요한 스킬은 무엇일까? 어느 분은 효과적인 알고리즘을 사용해 문제를 해결하는 스킬이라고 하지만, 본인은 무엇보다 '가독성 좋은 코드를 작성하는 스킬'이라고 생각한다.

그렇다면 어떻게 코드를 작성해야 할까? 이번 포스팅에서는 PEP8 기반으로 파이썬 코드를 가독성 있게 작성하는 법을 알아보도록 한다.

본 포스팅은 Al Sweigart의 저서인 『클린 코드, 이제는 파이썬이다』의 일부를 기반으로 작성되었습니다.

1. PEP 8에 대해서

PEP 8이란 무엇일까?

PEP 8(파이썬 개선 제안 8)은 파이썬 개발팀이 직접 제시한 스타일 가이드이다.

우리는 각자 고유의 코드 스타일을 가지고 있다. 컴파일러나 인터프리터는 어떤 코드 스타일이든 문제없이 해석하지만, 사람은 그럴 수 없다.

문제는 프로그래밍은 대부분 협동 작업이라는 점이다. 만약 팀원 각자의 코딩 스타일이 다르다면, 각자에 맞게 코드를 재포매팅 하는데 시간이 낭비될 것이다.

그래서 파이썬의 경우, PEP 8(Python Enhancement Proposal 8)이라는 공식적인 코드 스타일 가이드를 제시하고 있다. 이 규칙은 가독성 좋은 코드를 작성하는 법을 알려주며, 여러 코딩 스타일을 하나로 정립해 협업의 효율성을 높혀주기까지 한다.

PEP 8을 무조건 따라야 할까?

PEP 8의 의의는 코드 스타일을 하나하나 통제하기 위한 것이 아니라, 프로젝트의 일관성과 가독성 유지에 있다.

PEP 8에는 '일관성을 어리석게 고집하는 것은 좁은 생각에서 나오는 허깨비' 라는 섹션이 있다. 이 섹션에서는 스타일 가이드는 가독성 있는 코드 스타일을 정립해, 프로젝트 협업을 쉽게 만드는 것이 목표임을 상기시킨다.

PEP 8은 단순한 스타일 가이드일 뿐이고, 더 좋은 방법이 있다면 PEP 8을 준수하지 않아도 된다. 실제로 자신만의 스타일 가이드를 구축한 회사들도 많다.

하지만 PEP 8을 버리라는 소리는 아니다. PEP 8은 가독성 좋은 코드를 작성하는데 도움이 되며, 일부만 수용하더라도 PEP 8 문서를 읽어볼 가치는 있다.


2. 가독성 좋은 파이썬 코드를 작성하는 법

들여쓰기는 탭(tab)이 아닌, 공백 문자(' ')를 사용한다.

물론 둘다 문법상으로는 아무런 문제가 없다. 하지만 공백은 항상 같은 문자로 렌더링되는 데 반해, 탭 문자는 '\t'로 이스케이프 문자가 있어 렌더링이 모호하다.

또한 탭은 공백 폭이 가변이기 때문에 코드에 사용해서는 안된다. 탭스톱(tab stop)은 가변적으로 8칸 내외로 공백을 생성하며, 이는 들여쓰기(indent)로 로직을 구분하는 파이썬에게는 치명적이다. 심지어 Python 3.* 에서는 탭과 공백을 같이 사용하면 예외를 발생시킨다!

그래서 파이썬 코드의 보편적인 들여쓰기 관례는 공백 4칸이다. 이는 코드의 행 길이와 들여쓰기 구분을 고려한 결과이며, 대부분의 IDE는 tab을 사용하면 공백 4칸으로 치환한다.

연산자와 식별자 사이에 공백을 넣자

연산자와 식별자 사이에 공백이 없으면 코드가 하나로 결합된 듯이 보인다. 아래의 공백을 넣은 코드와 안넣은 코드를 비교해 보자.

# 공백을 넣은 코드 예
blanks = blanks[:i] + secretWord[i] + blanks[i + 1 :]
# 공백을 넣지 않은 코드 예
blanks=blanks[:i]+secretWord[i]+blanks[i+1:]

두 코드 + 연산자로 세 값을 더하지만, 공백을 안넣는 코드는 blanks[i+1:]의 +가 언뜻 네번째 값을 추가하려는 것처럼 보일 수 있다.

구분자 뒤쪽에 공백을 넣자

일반적인 개발 언어에서는 쉼표(,)를 이용해 파라미터와 배열의 원소 등을 구분한다. 이 때, 공백을 넣지 않으면 아래와 같이 '한데 뭉쳐져' 읽기 어려운 코드가 되어버린다.

# 공백을 넣지 않은 코드 예
def spam(eggs,bacon,ham):
	weights = [42.0,3.1415,2.718]

구분자 사이에 공백을 넣어 분리된 원소임을 강조하자. 공백을 넣은 아래 코드는 한 눈에 파라미터와 원소를 파악할 수 있다.

# 공백을 넣은 코드 예
def spam(eggs, bacon, ham):
	weights = [42.0, 3.1415, 2.718]

그렇다고 공백을 구분자 앞에 추가해서는 안 된다. 구분자를 강조하는 것이 아니라, 원소들을 분리하고자 함을 유의하자.

# 구분자 앞에도 공백을 넣은 코드 예
def spam(eggs , bacon , ham):
	weights = [42.0 , 3.1415 , 2.718]

코드 뒤 주석은 자제하되, 만약 쓴다면 공백 2칸으로 분리하자

Use inline comments sparingly. (인라인 코멘트는 아껴서 써라.)

- PEP 8 공식 문서에서 발췌

사실 본인은 코드 뒤 주석(inline comment, 이하 인라인 코멘트)를 좋아하지 않는다. 코드가 너무 길어져서 한 눈에 볼 수 없기 때문이다. 주석을 작성할 때는 별개의 행에 작성하는 블록 코멘트(Block Comment)를 사용하자.

인라인 코멘트와 블록 코멘트의 차이는 다음과 같다.

# 프로그램의 인사말을 출력하는 함수 << (Block Comment)
print('Hello, world!')

print('Hello, world!')  # 프로그램의 인사말을 출력하는 함수 << (Inline Comment)

만약 인라인 코멘트를 쓸 때에는, 코드 뒤에 공백 2칸을 붙여 주석과 코드를 분리하자. 공백이 하나거나 없으면 코드를 구분하기 어려워진다.

# 나쁜 예 (주석 앞에 공백을 붙이지 않음)
print('Hello, world!')# 프로그램의 인사말을 출력하는 함수

# 좋은 예 (주석 앞에 공백을 붙임)
print('Hello, world!')  # 프로그램의 인사말을 출력하는 함수

함수와 클래스는 두 줄의 빈 행을 넣고, 클래스 내의 메소드는 빈 행 한 줄을 넣자

세로 간격은 매우 긴 글에서 단락을 나누듯이, 특정 코드 행등을 그룹으로 묶고 분리하는 역할을 한다.

PEP 8에서는 함수나 클래스 사이는 두 줄의 빈 행을, 클래스 내 메소드는 빈 행 한 줄을 넣어 구분해야 한다고 명시한다. 아래 예시는 PEP 8의 세로 간격을 준수한 코드로, 클래스와 클래스 메소드, 함수가 한 눈에 구분되어 보인다.

# 클래스 내 메소드는 빈 행 한 줄로 구분한다.
class ExampleClass:
	def exampleMethod():
    	pass
        
	def exampleMethod2():
    	pass
        

# 클래스와 함수는 두 줄의 빈 행으로 구분한다.
def exampleFunction():
    pass

코드를 로직별로 한 줄의 빈 행을 넣어 구분하자

함수나 메소드가 길어지면 여러 개의 로직이 모이기 쉽상이며, 흐름을 이해해기 쉽지 않다. 이를 위해 프로그래머가 적절히 세로 행을 배치해 로직별로 코드를 분리해야 한다.

def validate_email(self, value):
	if not value or '@' not in value:
    	raise ValidationError("형식이 올바르지 않습니다.")
    
    user_part, domain_part = value.rsplit('@', 1)
    
    if not self.user_regex.match(user_part):
    	raise ValidationError("형식이 올바르지 않습니다.")
    
    ...

위 예시를 보자. 각 로직을 설명하는 주석이 없지만, 빈 행 덕분에 각 그룹이 개념적으로 서로 구분되어 있고, 각 그룹이 어떤 행위를 하는지 쉽게 파악할 수 있다.

import 문은 모듈당 하나씩, 종류를 나눠서 사용하자

파이썬에서는 import 문 하나로 여러 모듈을 가져올 수 있지만, PEP 8에서는 이를 권장하지 않는다. 이는 모듈의 사용 여부를 쉽게 알기 위함이며, 버전 관리 도구를 사용할 때도 도움이 된다.

또한 PEP 8에서는 다음과 같이 세 그룹으로 import 문을 분리하고, 순서대로 배치할 것을 권한다.

1. math, os, sys 등 파이썬 표준 라이브러리 모듈
2. 셀레늄, 리퀘스트, 장고 등 서드파티 모듈
3. 현재 작성 중인 프로그램의 일부인 로컬 모듈


3. 마치며

이번 포스팅에서 PEP 8 기반으로 '가독성 좋은 파이썬 코드를 작성하는 법'을 알아보았다.

파이썬의 최대 장점은 간결하고, 가독성 좋은 문법이라고 생각한다. 이러한 파이썬만의 장점을 이번 포스팅을 참고해 살려주었으면 한다.

profile
이도저도 아닌 개발자

0개의 댓글