-
Python으로 Clean Code 작성하기알.쓸.코드/알.쓸.파.코(알아두면 쓸데있는 파이썬 코드) 2022. 4. 10. 14:08반응형
Reference
아래 글을 참고하여 적는 글입니다. 대부분의 코드 예제는 아래 사이트에서 가져왔습니다.
https://dzone.com/articles/10-must-know-patterns-for-writing-clean-code-with-1
Must-Know Patterns: Writing Clean Code W/Python - DZone Open Source
Python is one of the cleanest programming languages. Yet developers still need to learn Python best practices to write clean code.
dzone.com
캡쳐한 코드(검은 배경화면)는 facebook 깃헙에서 가져온 코드입니다.
Clean Code란?
- Clean Code는 함수, 클래스 혹은 모듈이 한 가지에 집중해야 하고 잘 해야 한다.
- Clean Code는 읽기 쉬워야 한다.
- Clean Code는 디버그하기 쉬워야 한다.
- Clean Code는 유지 보수가 쉽다.
- Clean Code는 고성능이다.
Python에서 Clean Code를 작성하는 패턴
네이밍 규칙(Naming Convention)
변수, 함수, 클래스 등을 네이밍 할 때 목적이 드러나는 의미있는 이름을 사용해야 한다. 이는 짧고 애매모호한 이름보다 긴 설명으로 된 이름을 사용하는 것이 권장된다.
1. 읽기 쉽고 긴 설명으로 된 이름을 사용하자. 그러면 아래와 같이 불필요한 주석을 작성할 필요가 없다.
# Not recommended # The au variable is the number of active users au = 105 # Recommended total_active_users = 105
아래 코드에서 함수 이름을 'get_clip_embeddings', 'build_text_encoder' 등 사용 목적이 명확하게 드러나도록 네이밍 되어있어서 함수를 처음 보더라도 어떤 기능을 하는지 단번에 알 수 있다.
2. 서술적 목적을 드러내는 이름을 사용하자. 다른 개발자가 변수 이름에서 무엇을 저장하는지 알아 낼 수 있어야 한다. 즉, 코드는 읽기 쉽고 추론하기 쉬워야 한다.
# Not recommended c = [“UK”, “USA”, “UAE”] for x in c: print(x) # Recommended cities = [“UK”, “USA”, “UAE”] for city in cities: print(city)
아래 코드에서도 반복문을 사용할 때 i 혹은 x가 아닌 data와 iteration으로 표현하여 이 부분이 데이터 로더에서 데이터를 하나씩 꺼내 모델에 입력하여 훈련하는 부분일 것이라고 추론할 수 있다.
3. 줄여서 쓰지 말자. 변수는 애매모호한 짧은 이름보다 긴 설명으로 된 이름을 가져야 한다. 1번과 중복되는 말이다.
# Not recommended fn = 'John' Ln = 'Doe' cre_tmstp = 1621535852 # Recommended first_name = 'John' Las_name = 'Doe' creation_timestamp = 1621535852
4. 항상 동일한 어휘를 사용해야 한다. 당신만의 네이밍 규칙을 준수해야 한다. 일관된 네이밍 규칙을 지키는 것은 다른 개발자가 당신의 코드로 작업할 때 혼란을 없앨 수 있다. 이는 변수, 파일, 함수 심지어 디렉토리 구조에도 적용된다.
# Not recommended client_first_name = 'John' customer_last_name = 'Doe' # Recommended client_first_name = 'John' client_last_name = 'Doe' #Also, consider this example: #bad code def fetch_clients(response, variable): # do something pass def fetch_posts(res, var): # do something pass # Recommended def fetch_clients(response, variable): # do something pass def fetch_posts(response, variable): # do something pass
아래 코드에서 xxx_features, xxx_losses, cls_xxx 와 같이 일정한 네이밍 규칙을 준수한 것을 알 수 있다.
5. editor에서 codebase 문제 추적을 시작하자
Python codebase를 clean하게 유지하는 이유는 엔지니어가 코드 자체의 문제를 쉽게 추적하고 볼 수 있도록 하는 것이다. editor에서 codebase 문제를 추적하면 엔지니어는 다음을 수행할 수 있다.
- 기술적 부채에 대한 전체 가시성 확보
- 각 codebase 문제에 대한 context 참조
- context 전환 감소
- 지속적인 기술적 부채 해결
다양한 도구를 사용해 기술적 부채를 추적할 수 있지만 가장 빠르고 쉬운 방법은 Jira, Linear, Asana 및 프로젝트 관리 도구와 통합되는 VSCode 혹은 JetBrains 용 무료 확장을 사용하는 것이다.
6. magic number를 사용하지 말자.
magic number는 코드에 나타나지만 의미나 설명이 없는 특수하고 하드코딩된 의미를 가지는 숫자다. 숫자를 그대로 쓰지말고 변수에 할당해서 그 변수를 사용하라는 의미인 것 같다.
import random # Not recommended def roll_dice(): return random.randint(0, 4) # what is 4 supposed to represent? # Recommended DICE_SIDES = 4 def roll_dice(): return random.randint(0, DICE_SIDES)
함수(Functions)
7. 함수 네이밍 규칙을 준수하자
위의 변수에서 볼 수 있듯이 함수 이름을 지정할 때 네이밍 규칙을 따르자. 다른 네이밍 규칙을 사용하면 개발자에게 혼란을 줄 수 있다.
# Not recommended def get_users(): # do something Pass def fetch_user(id): # do something Pass def get_posts(): # do something Pass def fetch_post(id): # do something pass # Recommended def fetch_users(): # do something Pass def fetch_user(id): # do something Pass def fetch_posts(): # do something Pass def fetch_post(id): # do something pass
8. 함수는 한 가지 일을 잘 해야 한다.
단일 작업을 수행하는 짧고 간단한 함수를 작성하자. 참고할 만한 좋은 규칙은 함수 이름에 "and"가 포함된 경우 두 개의 함수를 분할해야 하는게 권장된다. 즉, 함수는 한 가지 일만 하도록 작성하자
# Not recommended def fetch_and_display_users(): users = [] # result from some api call for user in users: print(user) # Recommended def fetch_users(): users = [] # result from some api call return users def display_users(users): for user in users: print(user)
9. flag 혹은 boolean flag를 사용하자 말자
boolean flag는 boolean 값인 참 혹은 거짓을 가지는 변수이다. 이러한 flag는 함수에 전달되어 동작을 결정하는 데 사용된다.
text = "Python is a simple and elegant programming language." # Not recommended def transform_text(text, uppercase): if uppercase: return text.upper() else: return text.lower() uppercase_text = transform_text(text, True) lowercase_text = transform_text(text, False) # Recommended def transform_to_uppercase(text): return text.upper() def transform_to_lowercase(text): return text.lower() uppercase_text = transform_to_uppercase(text) lowercase_text = transform_to_lowercase(text)
클래스(Classes)
10. 중복되는 context를 추가하지 말자
이는 클래스로 작성할 때 변수 이름에 불필요한 변수 이름를 추가하여 발생할 수 있다. 아래와 같이 person 클래스에서 username이나 email 앞에 동일한 person이 추가되지 않도록 하자
# Not recommended class Person: def __init__(self, person_username, person_email, person_phone, person_address): self.person_username = person_username self.person_email = person_email self.person_phone = person_phone self.person_address = person_address # Recommended class Person: def __init__(self, username, email, phone, address): self.username = username self.email = email self.phone = phone self.address = address
11. 코드를 모듈화하자
코드를 구성하고 유지 관리할 수 있도록 하려면 logic을 모듈이라고 불리는 파일이나 클래스로 분할하자. Python에서 모듈은 단순히 .py 확장자로 끝나는 파일을 의미한다. 그리고 각 모듈은 한 가지 일을 잘 하는 데 집중해야 한다.
그리고 기본적인 OOP(object oriented principles)인 캡슐화(encapsulation), 추상화(abstraction), 상속(inheritance), 그리고 다형성(polymorphism)을 따라야 한다.
반응형'알.쓸.코드 > 알.쓸.파.코(알아두면 쓸데있는 파이썬 코드)' 카테고리의 다른 글
[Python] Swap (0) 2022.02.27 [Python] 간단한 Pytorch 코드 예제(MNIST) (0) 2021.10.20 [Python] 데이터프레임 중복 행, 중복 열 제거 (0) 2021.06.18 [Python] JSON 파일(.json) 저장하고 불러오기 (0) 2021.06.14