코딩을 하기 전에 설계와 문서가 선행되어야 하고 코딩 중에도 주석이 작성되어야 하지만 정말 바쁜 경우, 이를 생략하고 코딩을 할 때가 있습니다. 이럴 때 코딩 스타일 조차 뒤죽 박죽이면 정말 다시 읽기에 골치 아픈 상황이 발생할 수 있습니다.
더군다나 코드 작성법이 완전 다른 사람의 코드를 읽는다면 이는 더욱 힘에 부치는 작업이 될 수 있습니다.
(실제 상수, 클래스, 변수 네이밍을 지키지 않은 코드를 보면 정말 당황 할 수 있습니다….)
이를 방지하기 위해서 코딩 스타일을 규정하는 코딩 컨벤션이 존재합니다.
코드 컨벤션을 언어마다 다릅니다. 파이썬의 코딩 컨벤션은 PEP8 이라고 합니다.
autopep8 패키지도 자동 포맷팅도 있으나 완벽하지 않으니 평소에 숙지해서 사용하면 좋을 것 같습니다.
이번 포스트에서는 파이썬의 코딩 컨벤션, PEP8에 대해 정리해보았습니다.
PEP8 정리 1 : 네이밍 컨벤션
타입 | 네이밍 컨벤션 | 예 |
---|---|---|
함수 | 소문자 단어를 사용하세요. 가독성을 높이려면 단어를 밑줄로 구분하세요. | function, my_function |
변수 | 소문자 단일 문자, 단어를 사용하세요. 가독성을 높이려면 단어를 밑줄로 구분하세요. | x, var, my_variable |
클래스 | 각 단어를 대문자로 시작하세요. 밑줄로 단어를 구분하지 마세요. 이 스타일을 파스칼 케이스라고 합니다. | Model, MyClass |
상수 | 소문자 단어를 사용하세요. 가독성을 높이려면 단어를 밑줄로 구분하세요. | CONSTANT, MY_CONSTANT, MY_LONG_CONSTANT |
모듈 | 짧은 소문자 단어를 사용하세요. 가독성을 높이려면 단어를 밑줄로 구분하세요. | module.py, my_module.py |
패키지 | 짧은 소문자 단어를 사용하세요. 밑줄로 단어를 구분하지 마세요.. | package, mypackage |
권장 코드 예제
# 변수명은 소문자와 단어 간 언더스코어(_)를 사용하여 짓습니다.
user_name = "John Doe"
# 함수명도 소문자와 언더스코어를 사용합니다.
def calculate_average(numbers):
# 코드 내용
pass
# 클래스명은 파스칼 표기법으로 작성합니다.
class MyCalculator:
# 클래스 멤버나 메소드도 소문자와 언더스코어를 사용합니다.
def add_numbers(self, num1, num2):
# 코드 내용
pass
권장하지 않는 코드 예제
# 변수명에 언더스코어를 사용하지 않음.
UserName = "John Doe"
# 함수명에 파스칼 표기법을 사용함.
def CalculateAverage(numbers):
# 코드 내용
pass
# 클래스명에 소문자를 사용함.
class my_calculator:
# 클래스 멤버나 메소드에도 소문자를 사용함.
def AddNumbers(self, num1, num2):
# 코드 내용
pass
PEP8 정리 2 : Blank line
PEP8은 공백 라인을 사용하여 코드 블록을 논리적으로 구분하고 일관성을 유지하는 것을 권장합니다. 이는 코드의 가독성을 향상시키고 코드의 논리적인 구조를 강조하는 데 도움이 됩니다.
- 클래스 사이 2줄 빈칸
- 클래스 내부 메소드 사이는 한 줄 빈칸
권장 코드 예제
def calculate_average(numbers):
total = sum(numbers)
count = len(numbers)
average = total / count
return average
class Calculator:
def add(self, num1, num2):
return num1 + num2
def subtract(self, num1, num2):
return num1 - num2
권장하지 않는 코드 예제
def calculate_average(numbers):
total = sum(numbers)
count = len(numbers)
average = total / count
return average
class Calculator:
def add(self, num1, num2):
return num1 + num2
def subtract(self, num1, num2):
return num1 - num2
- 좋은 예에서는 함수와 클래스 간에 빈 줄을 사용하여 각각의 논리적인 블록을 구분하고 있습니다.
- 나쁜 예에서는 빈 줄의 부족으로 함수와 클래스 간의 구분이 덜 명확하며, 가독성이 떨어집니다
PEP8에서는 함수 내의 복잡한 단계를 거치는 경우 각 단계 전에 빈 줄을 두어 가독성을 향상시키라고 권장합니다.
권장 코드 예제
def complex_function(data):
# 단계 1: 데이터 전처리
processed_data = preprocess_data(data)
# 빈 줄을 사용하여 논리적인 단계를 구분
# 단계 2: 특징 추출
features = extract_features(processed_data)
# 단계 3: 모델 훈련
model = train_model(features)
# 단계 4: 예측 수행
predictions = make_predictions(model, features)
return predictions
권장하지 않는 코드 예제
def complex_function(data):
processed_data = preprocess_data(data)
features = extract_features(processed_data)
model = train_model(features)
predictions = make_predictions(model, features)
return predictions
PEP8 정리 3 : 최대 줄 길이와 줄 끊기
PEP8에서는 코드의 최대 줄 길이를 79자로 권장하고 있습니다. 더 긴 줄은 읽기 어렵고 출력되는 환경에 따라 문제를 일으킬 수 있습니다. 또한, 더 긴 줄은 코드 리뷰 및 협업에서도 불편함을 초래할 수 있습니다.
권장 코드 예제
# 최대 줄 길이를 지키고 줄 끊기를 사용한 예제
def example_function(parameter1, parameter2, parameter3,
parameter4, parameter5):
result = parameter1 + parameter2 + parameter3 + \
parameter4 + parameter5
return result
권장하지 않는 코드 예제
# 최대 줄 길이를 넘기는 예제
def example_function(parameter1, parameter2, parameter3, parameter4, parameter5):
result = parameter1 + parameter2 + parameter3 + parameter4 + parameter5
return result
PEP8 정리 4 : 함수 인자의 들여쓰기
PEP8에서는 함수의 인자들을 들여쓰기할 때 일관된 스타일을 유지하고자 권장하는 규칙이 있습니다. 이 규칙은 여러 줄에 걸친 함수 인자를 명확하게 표현하고 가독성을 향상시키는 데 도움이 됩니다.
권장 코드 예제
# 함수 인자들을 일관된 들여쓰기로 표현하는 예제
def example_function(
parameter1, parameter2, parameter3,
parameter4, parameter5):
result = parameter1 + parameter2 + parameter3 + \
parameter4 + parameter5
return result
권장하지 않는 코드 예제
# 들여쓰기를 일관되게 지키지 않는 예제
def example_function(
parameter1, parameter2, parameter3,
parameter4, parameter5):
result = parameter1 + parameter2 + parameter3 + \
parameter4 + parameter5
return result
PEP8 정리 5 : 주석
단위 주석
PEP8에서는 단위 주석(unit comments)을 피하도록 권장하고 있습니다. 대신 코드의 구조와 변수/함수의 네이밍을 통해 자체 설명력을 갖추도록 권고하고 있습니다. 단위 주석은 코드를 읽기 어렵게 만들 수 있고, 코드가 변할 때 주석을 업데이트하는 일이 번거로울 수 있습니다.
권장 코드 예제
# 단위 주석을 피하고 코드 구조와 변수/함수명으로 설명
def calculate_total_price(quantity, price_per_unit):
"""
Calculate the total price.
Args:
quantity (int): The quantity of items.
price_per_unit (float): The price per unit.
Returns:
float: The total price.
"""
total_price = quantity * price_per_unit
return total_price
권장하지 않는 코드 예제
# 단위 주석을 사용한 예제
def calculate_total_price(quantity, price_per_unit):
# Calculate the total price
# Args:
# quantity (int): The quantity of items.
# price_per_unit (float): The price per unit.
# Returns:
# float: The total price.
total_price = quantity * price_per_unit
return total_price
inline 주석
PEP8에서는 인라인 주석(inline comments)을 적게 사용하고 가독성이 있는 코드를 선호합니다. 인라인 주석이 너무 많거나 남발되면 코드의 가독성이 저하될 수 있습니다. 코드 자체가 명확한 주석이 필요 없도록 작성되도록 권장하고 있습니다
필요한 경우, 코드와 inline 주석은 2개 이상의 빈칸을 두고 작성합니다
권장 코드 예제
# 인라인 주석을 피하고 코드 자체로 설명
result = value1 + value2
권장하지 않는 코드 예제
# 너무 많은 인라인 주석을 사용한 예제
result = value1 + value2 # Add value1 and value2 (calculate sum)
PEP8 정리 6 : 공백
연산자 공백
PEP8에서는 연산자 주변에 공백을 사용하여 코드를 가독성 있게 작성하는 것을 권장합니다.
권장 코드 예제
# 연산자 주변에 공백을 사용한 예제
result = value1 + value2 - value3 * (value4 / value5)
권장하지 않는 코드 예제
# 연산자 주변에 공백을 사용하지 않은 예제
result = value1+value2-value3*(value4/value5)
슬라이스 공백
PEP8에서는 슬라이스(slice) 표현식을 사용할 때, 콜론(:
) 주변에 공백을 사용하여 코드를 가독성 있게 작성하는 것을 권장합니다.
권장 코드 예제
# 슬라이스 표현식에서 공백을 사용한 예제
sublist = my_list[start_index : end_index]
권장하지 않는 코드 예제
# 슬라이스 표현식에서 공백을 사용하지 않은 예제
sublist = my_list[start_index:end_index]
공백을 넣지 말아야 할 때
라인의 끝에서는 절대 공백을 넣지 않습니다.
괄호 안쪽에 공백을 넣지 않습니다.
콤마, 세미콜론, 콜론 앞에 공백 넣지 않습니다.
권장 코드 예제
# 괄호 주변에 공백을 사용하지 않은 예제
result = sum([1, 2, 3])
권장하지 않는 코드 예제
# 괄호 주변에 공백을 사용한 예제
result = sum( [1, 2, 3] )
PEP8 정리 7 : 모호성을 줄이는 프로그래밍
PEP8에서는 True와 등가성 연산자(equivalence operator)를 함께 사용하지 않도록 권장하고 있습니다. True는 이미 참(또는 1)을 나타내므로 등가성 비교를 추가로 사용하는 것은 불필요합니다.
권장 코드 예제
if result:
print("Result is True")
권장하지 않는 코드 예제
if result == True:
print("Result is True")
PEP8 정리 8 : import 순서
프로젝트 수준으로 가면 import 모듈이 많아질 수 있고 이게 자체 모듈인지 표준 라이브러리 모듈인지 헷갈릴 수 있습니다. PEP8에서는 모듈을 가져오는(import) 순서에 관한 규칙을 정의하고 있습니다
다음 3 분류들을 표준 라이브러리 모듈 -> 관련 써드파티 모듈 -> 자체 모듈 순서로 가져옵니다.
각 분류에서 여러 모듈들은 알파벳 순으로 가져옵니다
권장 코드 예제
# 권장되는 import 순서의 예제
import os
import sys
from module1 import function1
from module2 import function2
권장하지 않는 코드 예제
# 권장되지 않는 import 순서의 예제
from module1 import function1
import sys
from module2 import function2
import os