파이썬에서의 베스트 프랙티스
이 글은 파이썬의 베스트 프랙티스를 설명합니다.
실제 코드 예제를 통해 파이썬 베스트 프랙티스와 읽기 쉽고 유지보수하기 쉬운 코드를 작성하는 방법을 소개합니다.
YouTube Video
파이썬에서의 베스트 프랙티스
가독성을 최우선으로 하세요
먼저 ‘가독성을 최우선으로 하자’에 대해 살펴보겠습니다.
파이썬은 ‘가독성’을 중요시하는 언어입니다. 먼저, 의도가 한눈에 드러나는 코드를 작성하는 것을 우선시하세요.
1# Bad example: unclear variable names
2a = 10
3b = 5
4c = a * b이 코드에서는 변수명이 그 의미를 전달하지 않아, 다른 사람이 나중에 이해하는 데 시간이 걸립니다.
1# Good example: descriptive variable names
2price = 10
3quantity = 5
4total_cost = price * quantity변수명을 구체적으로 하면 코드 자체가 문서 역할을 하게 됩니다.
명확한 코드를 작성하세요
다음으로 ‘명확한 코드 작성’에 대해 살펴보겠습니다.
파이썬에서는 '암묵적인 동작'보다 '명확한 의도'가 선호됩니다.
1# Bad example: implicit truthy check
2if data:
3 process(data)이 코드에서는 data에 무엇이 기대되는지 불분명해서 버그가 발생하기 쉽습니다.
1# Good example: explicit condition
2if len(data) > 0:
3 process(data)조건을 명확하게 하면 코드의 의도와 사양이 일치합니다.
함수는 작게, 한 가지 책임에만 집중하도록 하세요
다음으로 ‘함수를 작게, 한 가지 책임에만 집중시키는 것’에 대해 살펴보겠습니다.
하나의 함수가 너무 많은 일을 하면 테스트와 유지보수가 어려워집니다.
1# Bad example: doing too many things
2def handle_user(user):
3 save_to_database(user)
4 send_email(user)
5 write_log(user)이 코드에서는 처리 과정이 밀접하게 얽혀 있어 재사용과 수정이 어렵습니다.
1# Good example: single responsibility
2def save_user(user):
3 save_to_database(user)
4
5def notify_user(user):
6 send_email(user)
7
8def log_user(user):
9 write_log(user)함수를 분리하면 역할이 명확해지고 테스트도 쉬워집니다.
타입 힌트를 적극적으로 사용하세요
다음으로 ‘타입 힌트 적극 사용’을 살펴보겠습니다.
타입 힌트는 문서 역할도 하며, 버그 예방에 강력한 도구입니다.
1# Bad example: Without type hints
2def add(a, b):
3 return a + b이 코드에서는 인수와 반환값의 타입이 불분명해 잘못 사용하기 쉽습니다.
1# Good example: With type hints
2def add(a: int, b: int) -> int:
3 return a + b타입 힌트를 사용하면 IDE 자동완성과 정적 분석, 가독성이 크게 향상됩니다.
None 반환 가능성을 명확히 표시하세요
다음으로 ‘None 반환 가능성의 명시’를 살펴보겠습니다.
None을 반환할 수 있는 함수는 사용하는 사람이 놓치기 쉽습니다.
1# Bad example: Ambiguous return value
2def find_user(user_id):
3 if user_id == 1:
4 return {"id": 1, "name": "Alice"}
5 return None이 코드에서는 반환값이 있는지 불명확합니다.
1# Good example: explicit return type
2from typing import Optional, Dict, Any
3
4def find_user(user_id: int) -> Optional[Dict[str, Any]]:
5 if user_id == 1:
6 return {"id": 1, "name": "Alice"}
7 return NoneOptional을 사용하여 None 반환 가능성을 타입으로 전달할 수 있습니다.
예외를 너무 넓게 처리하지 마세요
다음으로 ‘예외를 너무 넓게 잡지 않기’를 살펴보겠습니다.
예외 처리는 기본적으로 필요한 것만 잡아야 합니다.
1# Bad example: catching all exceptions
2try:
3 result = int(value)
4except Exception:
5 result = 0이 코드는 발견되어야 할 버그를 숨길 수 있습니다.
1# Good example: catch specific exception
2try:
3 result = int(value)
4except ValueError:
5 result = 0예외 범위를 제한하면 예상치 못한 문제를 간과하지 않을 수 있습니다.
with문으로 안전하게 리소스를 처리하세요
다음으로 'with문으로 리소스 안전하게 처리하기'를 살펴보겠습니다.
파일이나 락과 같은 리소스는 항상 안전하게 해제해야 합니다.
1# Bad example: manual close
2file = open("data.txt")
3content = file.read()
4file.close()이 코드에서는 예외가 발생하면 close()가 호출되지 않을 수 있습니다.
1# Good example: using context manager
2with open("data.txt") as file:
3 content = file.read()with문을 사용하면 예외가 발생해도 안전하게 정리가 이뤄집니다.
리스트 컴프리헨션을 적절히 사용하세요
다음으로 ‘리스트 컴프리헨션 적절히 사용하기’를 살펴보겠습니다.
간단한 변환 처리는 리스트 컴프리헨션을 사용하여 간결하게 쓸 수 있습니다.
1# Bad example: Verbose loop
2squares = []
3for i in range(10):
4 squares.append(i * i)이 코드에서는 핵심 처리가 잘 보이지 않습니다.
1# Good example: Clear list comprehension
2squares = [i * i for i in range(10)]리스트 컴프리헨션을 적절히 사용하면 코드의 가독성이 향상됩니다.
매직 넘버를 피하세요
다음으로 ‘매직 넘버 피하기’를 살펴보겠습니다.
숫자나 문자열을 직접 작성하면 의미가 불분명해집니다.
1# Bad example: magic number
2if status == 404:
3 handle_not_found()이 코드에서는 404의 의미를 알고 있을 것이라고 가정하고 있습니다.
1# Good example: named constant
2NOT_FOUND = 404
3
4if status == NOT_FOUND:
5 handle_not_found()이름을 지정함으로써 의도를 명확하게 할 수 있습니다.
'동작하는 코드'가 아니라 '유지보수할 수 있는 코드'를 작성하세요
마지막으로 '동작만 하는 코드'가 아니라 '유지보수 가능한 코드 작성'에 대해 살펴보겠습니다.
중요한 점은 미래의 자신이나 다른 사람이 읽을 수 있느냐입니다.
1# Bad example: Hard to maintain
2def f(x):
3 return x * 1.08 + 100이 코드에서는 사양을 코드만 보고 파악할 수 없습니다.
1# Good example: Easy to maintain
2TAX_RATE = 1.08
3BASE_FEE = 100
4
5def calculate_total(price: float) -> float:
6 return price * TAX_RATE + BASE_FEE의미를 이름에 반영하면 코드 자체가 사양이 됩니다.
요약
파이썬의 베스트 프랙티스는 영리한 코드보다 이해하기 쉬운 코드를 작성하는 것으로 귀결됩니다. 작은 습관을 쌓으면 버그가 적고 오래 사용할 수 있는 코드로 이어집니다.
위의 기사를 보면서 Visual Studio Code를 사용해 우리 유튜브 채널에서 함께 따라할 수 있습니다. 유튜브 채널도 확인해 주세요.