-
Python - Clean code - better/good/bad examplesPython 2021. 2. 10. 11:10
github.com/zedr/clean-code-python
zedr/clean-code-python
:bathtub: Clean Code concepts adapted for Python. Contribute to zedr/clean-code-python development by creating an account on GitHub.
github.com
Use meaningful and pronounceable variable namesimport datetime ## bad ymdstr = datetime.date.today().strftime("%y-%m-%d") ## good current_date: str = datetime.date.today().strftime("%y-%m-%d")Use the same vocabulary for the same type of variable
## bad def get_user_info(): pass def get_client_data(): pass def get_customer_record(): pass ## good def get_user_info(): pass def get_user_data(): pass def get_user_record(): pass ## better from typing import Union, Dict, Text class Record: pass class User: info : str @property def data(self) -> Dict[Text, Text]: return {} def get_record(self) -> Union[Record, None]: return Record()Use searchable names
import time ## bad time.sleep(86400) ## good SECONDS_IN_A_DAY = 60 * 60 * 24 time.sleep(SECONDS_IN_A_DAY)Use explanatory variables
## bad import re address = "One Infinite Loop, Cupertino 95014" city_zip_code_regex = r"^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$" matches = re.match(city_zip_code_regex, address) if matches: print(f"{matches[1]}: {matches[2]}") ## good address = "One Infinite Loop, Cupertino 95014" city_zip_code_regex = r"^[^,\\]+[,\\\s]+(?P<city>.+?)\s*(?P<zip_code>\d{5})?$" matches = re.match(city_zip_code_regex, address) if matches: print(f"{matches['city']}, {matches['zip_code']}")Avoid Mental Mapping
seq = ("Austin", "New York", "San Francisco") ## bad for item in seq: print(item) ## good for location in locations: print(location)Don"t add unneeded context
## bad class Car: car_make: str car_model: str car_color: str ## good class Car: make: str model: str color: strUse default arguments instead of short circuiting or conditionals
from typing import Text import hashlib ## bad def create_micro_brewery(name): name = "Hipster Brew Co." if name is None else name slug = hashlib.sha1(name.encode()).hexdigest() # etc. ## good def create_micro_brewery(name: Text = "Hipster Brew Co."): slug = hashlib.sha1(name.encode()).hexdigest() # etc.Functions should do one thing
from typing import List class Client: active: bool def email(client: Client) -> None: pass def email_clients(clients: List[Client]) -> None: """Filter active clients and send them an email. """ for client in clients: if client.active: email(client) ## good def get_active_clients(clients: List[Client]) -> List[Client]: """Filter active clients. """ return [client for client in clients if client.active] ## good def email_clients(clients: List[Client]) -> None: """Send an email to a given list of clients. """ for client in get_active_clients(clients): email(client) ## better def active_clients(clients: Iterator[Client]) -> Generator[Client, None, None]: """Only active clients""" return (client for client in clients if client.active) ## better def email_client(clients: Iterator[Client]) -> None: """Send an email to a given list of clients. """ for client in active_clients(clients): email(client)Function names should say what they do
class Email: ## bad def handle(self) -> None: pass ## good def send(self) -> None: """Send this message""" message = Email() message.send()Don't use flags as function parameters
- flag를 통해 분기로 다른 일을 한다면 함수가 두 개 이상의 일은 한다는 것이므로 분리시켜야함
from typing import Text from tempfile import gettempdir from pathlib import Path ## bad def create_file(name: Text, temp: bool) -> None: if temp: (Path(gettempdir()) / name).touch() else: Path(name).touch() ## good def create_file(name: Text) -> None: Path(name).touch() ## good def create_temp_file(name: Text) -> None: (Path(gettempdir()) / name).touch()Comments
- 비즈니스 로직이 복잡한 경우에만 주석을 달자. 코드 자체를 설명할 필요는 없음
- 주석으로 된 코드는 남기지 않기 - git 으로 관리
- 코드 위치 남기지 않기
'Python' 카테고리의 다른 글
OOP - 상속,변수, 초기화- Crawling/Custom Exceptions (0) 2022.01.13 [TEST] 2.테스트 코드 작성하기 (0) 2021.10.24 객체 지향 프로그래밍 - 크롤러 개발 (0) 2021.10.12 Python 3.8 new features (0) 2021.02.10 Process / thread (0) 2020.11.04