본문 바로가기
Uncategorized

[Python]파이썬 코드는 어떻게 작성해야할까? - PEP 8

by NoiB 2022. 11. 22.
반응형

대학을 다니면서 프로그래밍 입문 강의를 들었을 때는 변수든 함수든 이름 지을 때 띄어쓰기는 못하니까 띄어쓰기 대신 언더스코어('_')를 쓰라는 교육을 받았습니다. 그러다 또 다른 교수님은 자기는 언더스코어 쓰는 거 꼴 보기 싫으니까 대문자로 연결을 하라고 했었죠(main_func이라면 mainFunc처럼). 그때까지만 해도 네이밍이 개인의 기호에 따라 달라지는 것이다라고 생각을 했던 것 같아요(아마 꼴 보기 싫으니까 하지 말라고 했던 교수님의 영향이 좀 있었던 것 같은데요). 그래서 그렇게 알고만 있었는데 시간이 좀 지나고 나서 함께 프로젝트를 진행했던 친구가 명명 규약(Naming Convention)에 대해서 알려줬습니다. 그제야 아 이게 정해진 규칙들이 있구나 하는 걸 알게 되었네요. 서론이 길었는데 그래서 오늘 알아볼 것은 파이썬에서의 Coding Convention, 코딩 규칙입니다.

 

파이썬은 오픈 소스인 만큼, 많은 개발자들이 참여해서 파이썬의 발전을 위한 논의를 하고 있습니다. 그래서 그런 논의를 기록으로 남겨왔는데요. 그런 기록들이 PEP(Python Enhancement Proposal)라는 이름으로 문서화되어 있습니다. 오늘 얘기할 내용은 PEP 8 - Style Guide for Python Code, 파이썬 코드를 위한 스타일 가이드입니다. Coding Convention(코딩 규약)이라고도 부르지만 법처럼 강제되는 것은 아니구요. 이렇게 작성해주면 좋겠다~입니다. 일을 하다 보면 내가 짠 코드를 남이 보는 일이 수없이 많기 때문에 남들이 봐도 편하게 '파이썬 코드를 이런 형식으로 작성해주면 좋겠어'하고 제시하는 가이드라인인 것이죠. 하지만 본인이 현재 진행 중인 프로젝트에서 정해진 규칙이 있다면 해당 규칙을 우선하는 것이 좋습니다. 결국 같이 일할 때 편하기 위해서 하는 것이니까요.

 

들여 쓰기(Indentation)

처음 알아볼 것은 '들여 쓰기'입니다. 파이썬의 경우 C 기반의 다른 대부분의 언어와 달리 코드 블럭을 중괄호({}) 대신 들여 쓰기로 판단합니다.

//C
#include <stdio.h>

void main(){
	printf("Hello World")
}

 

#Python
def main():
	print('Hello World')

들여 쓰기는 기본적으로 space 4번이나 tab 1회를 권장합니다. 하지만 space를 몇 번을 치든 하나의 코드 블럭 내에서 들여 쓰기의 길이만 맞춰준다면 Syntax Error가 뜨지는 않기 때문에 가끔 보면 space 1회로 들여 쓰기가 되어있는 코드도 심심치 않게 볼 수 있습니다. 

 

띄어쓰기

여러 가지 경우에 대한 앞뒤 띄어쓰기입니다(쉼표에 대한 띄어쓰기는 따로 작성하지는 않겠으나 공식 문서에 있으니 살펴보시면 좋을 것 같습니다).

 

대입 및 산술 연산:

# Correct:
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)

# Wrong:
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)

파라미터:

# Correct:
def complex(real, imag=0.0):
    return magic(r=real, i=imag)
    
# Wrong:
def complex(real, imag = 0.0):
    return magic(r = real, i = imag)

위 두 가지 외에도 많은 예시가 있지만 자주 작성하는 두 가지만 가져와봤습니다. 파라미터는 저도 제법 최근까지 대입 연산자 앞뒤에 띄어쓰기를 넣었는데 최근에는 안 하려고 노력 중입니다.

 

주석

코드를 작성할 때 상당히 귀찮지만 무조건 해야 하는 일이 바로 주석을 다는 것입니다. 주석을 달아놓은 코드와 달지 않은 코드는 가독성 및 유지 보수면에서 압도적인 편의성 차이가 나타나게 됩니다. 아마 다들 예전의 자신이 왜 저런 식으로 코드를 짠 거지 하는 경험을 몇 번 해보신 적 있으실 것 같은데요. 계속해서 말하지만 자신뿐만 아니라 함께 일할 팀원 혹은 다른 사람을 위해 주석을 꼭 다는 게 좋겠죠.

# This is how to use the comments.

기본적으로 주석은 위와 같이 하나의 #과 뒤에 올 문장으로 구성됩니다. 가이드라인은 #이후에 한 번 띄우고 제대로 된 문장을 영어로 작성하는 것입니다. 주석을 다는 것은 중요하지만 너무 많은 inline comments(코드 바로 옆에 작성하는 주석)는 피하는 것이 좋고, 그렇기 때문에 너무 당연한 내용을 작성하지 않는 것이 중요하다고 합니다.

x = x + 1                 # Increment x

예를 들면 이렇게 'x가 커진다'와 같은 당연한 내용은 지양해야 되겠죠. 그리고 제대로 된 문장(대문자로 시작해서 문장 구조를 잘 맞추고 마지막에는 마침표로 끝나는)으로 작성하는 것이 추천된다고 하네요. 작성 언어는 영어를 추천합니다만 해당 코드는 절대 영어를 아는 사람이 볼 일이 없다는 확신(말이 안 되지만)이 든다면 굳이 영어로 작성할 필요는 없겠죠. 다만 encoding 방식에 따라 특히 한글 주석은 깨질 위험이 있으니 가급적이면 영어로 작성하는 것이 좋습니다.

'''한 줄 짜리 내용'''

'''한 줄
두 줄
'''

'''
한 줄
두 줄
'''

"""쌍따옴표로 작성해도 됨. 공식문서에서는 쌍따옴표만 사용하고 있긴 함."""

여러 줄로 된 주석을 작성할 때는 위와 같은 방법으로 작성을 합니다. 따옴표 또는 큰따옴표 3개로 열고 내용을 작성한 다음 다시 3개로 닫아주면 됩니다. 위와 같은 주석을 Documentation Strings(a.k.a. docstrings)라고 부릅니다. 모듈, 클래스, 메서드, 함수 등을 설명하기 위해 선언하고 코드 블럭 내부에서 가장 위에 작성하는 주석입니다. C 같은 데서 /**/ 안에 작성하는 것과 같다고 보시면 됩니다. IDE에서 함수나 클래스에 마우스를 갖다 대면 이게 뭔지, 어떻게 사용하는지 설명이 막 나오는 걸 보신 적 있으실 텐데 이렇게 작성한 주석이 그렇게 설명으로 나오게 됩니다. Markdown 문법도 인식하기 때문에 노력을 들이면 좀 더 가독성이 좋은 docstrings를 작성할 수 있습니다.

 

명명 규칙(Naming Convention)

가장 중요하다고 볼 수 있는 명명 규칙입니다. 변수의 이름은 어떻게 해야 하는지, 함수의 이름은 어떻게 지어야 하는지 등의 규칙들이 여기에 포함이 되죠. 하나씩 알아보도록 합시다.

 

먼저 피해야 할 이름입니다. 변수 이름에 단일 문자 l(소문자 el), O(대문자 oh), I(대문자 eye)를 사용하는 것을 피해야 합니다. 폰트에 따라 다르지만 특정 폰트에서 숫자 1 및 0과 구분이 되지 않는 경우가 있다고 하네요. 사실 요즘 사람들이 사용하는 대부분의 ide에서는 문자와 정수는 아예 색이 다르게 표시되어서 크게 이런 경우가 없긴 하겠지만 아예 cli로 콘솔 창에서 작업을 하는 사람들도 가끔 있기 때문에 정말 부득이하게 사용해야 하는 이유가 아니라면 사용하지 않는 게 좋은 방법일 것 같습니다.

 

다음으로는 ASCII 호환성입니다. 아스키코드로 표현할 수 있는 문자만 사용하라는 뜻이겠죠.

 

이미 파이썬에서 사용하고 있는 이름은 사용하지 않는 것이 좋습니다. 예를 들어 특정 리스트의 이름을 list로 짓거나 range라는 변수를 만든다거나 하는 기초적인 실수들이 있겠죠.

 

패키지 및 모듈 이름은 모두 소문자여야 합니다. 흔히 사용하는 os, sys 등의 모듈을 보면 전부 소문자인걸 알 수 있는데요. 가독성 향상을 위해 언더스코어를 사용할 수는 있지만 권장하지는 않는다고 하네요.

 

클래스 이름은 일반적으로 CapWords 규칙을 따라야 합니다. CapWords규칙은 UpperCamelCase, PascalCase 등으로 불리기도 하는 방법입니다. 대문자로 시작하고 단어의 구분이 있을 때 첫 글자를 대문자로 작성하는 방법이죠.

 

함수 및 변수 이름은 소문자로 작성하고 단어 구분을 언더스코어로 구성하는 snake_case를 사용합니다. 이전 버전 또는 다른 언어에서 lowerCamelCase를 사용하는 경우와 호환성을 유지하기 위해 특정 상황에 한해서 lowerCamelCase를 허용한다고 하네요.

 

메서드 및 인스턴스의 이름 또한 함수처럼 snake_case를 따릅니다. 또한 private 메서드나 인스턴스에 대해 선행 밑줄을 사용할 수 있습니다(_my_method).

 

모듈과 함께 정의되는 상수의 경우는 모두 대문자 및 밑줄로 구성합니다. C의 #define(매크로)과 동일합니다. SCREAMING_SNAKE_CASE나 UPPER_CASE_WITH_UNDERSCORES라고도 부릅니다.

 

# 패키지, 라이브러리, 모듈의 이름은 소문자
import sys
import os

# 상수의 이름은 SCREAMING_SNAKE_CASE
MAX_NUM = 100

# 쿨래스 이름은 PascalCase, 메서드 이름은 snake_case
class MyClass:
	def __init__(self):
		self.name = 'MyClass'
        
	def my_method():
		return
        
# 함수, 변수 이름은 snake_case
def my_func():
	result_num = 0
	return result_num

 

제가 생각했을 때 중요하다고 생각하는 내용들만 뽑아서 정리를 해봤습니다만, 작성하지 않은 내용들에도 알아두면 좋을 내용이 많이 있으니 추가적으로 궁금하시다면 글 처음에 하이퍼링크를 걸어놓은 PEP 8을 직접 보는 것을 추천드립니다.

반응형