0w0

자잘하지만 알려주고 싶었던 선배의 코드리뷰

자잘하지만 알려주고 싶었던 선배의 코드리뷰

들어감에

신입일 때 선배의 코드 리뷰를 받을 떄마다 자주 들은 것이,

'음... 자잘한 지적이지만 나라면 이렇게 쓸 것 같은데. 뭐 틀리지는 않았어도'

당초에는 그 감사함은 모르고, 투털대면 수정했지만,

지금 와서 선배의 '자잘하지만 알려주고 싶어' 그 마음을 알 것 같습니다.

선배의 지적사항(Python 예시)

싱글 쿼터인가 더블 쿼터인가

print('I\'ll be back')
print("I'll be back")

에스케이프가 필요없는 작성법으로.

메서드명은 길어도 OK

def check_file(file_name: str) -> bool:
    # check if a file exists
def check_if_file_exists(file_name: str) -> bool:
    # 처리

메서드명에서 기능을 알아 채릴 수 있도록 (주석보다 효과적)

같은 처리를 몇 번씩 쓰지 않는다

def func1():
    if cond1:
        do_if()
    else:
        do_else()

def func2():
    if cond1:
        do_if()
    else:
        do_else()
def common_process():
    if cond1:
        do_if()
    else:
        do_else()

def func1():
    common_process()

def func2():
    common_process()

같은 처리는 메서드를 만들어 가독성/유지보수성 향상시키자

값이 지정 범위 포함한가 체크

# (0, 100) 구간 포함하는 경우
if val > 0 and val < 100:
    do_something1()
# [0, 100] 구간 포함하지 않는 경우
if val < 0 or val > 100:
    do_something2()
# (0, 100) 구간 포함하는 경우
if 0 < val < 100:
    do_something1()
# [0, 100] 구간 포함하지 않는 경우
if val < 0 or 100 < val:
    do_something2()

수학 구간 기법(0, 100)과 유사해 알기 쉽다?

여분의 변수를 만들지 않는다.

def get_basic_info(student: Student) -> dict:
    name = student.name
    age = student.age
    birth = student.birth
    basic_info = {
        "name": name,
        "age": age,
        "birth": birth
    }
    return basic_info
def get_basic_info(student: Student) -> dict:
    basic_info = {
        "name": student.name,
        "age": student.age,
        "birth": student.birth,
    }
    return basic_info

변수낭비, 프로그램이 장황해진다.

dict 마지막에 , 남겨도 ㅇㅋ

None, 공백문자열을 동시 체크

if val is None or val == "":
    do_something()
if not val:
    do_something()

하나의 not으로 끝난다

맨 처음 이상처리해서 return 시킨다

  if cond1:
    if cond2:
        # 정상처리
        ... ...
        ... ...
        ... ...
    else:
        # 이상처리(에러 로그 출력 같은)
  else:
    # 이상처리(에러 로그 출력 같은)
if not cond1:
    # 이상처리(에러 로그 출력 같은)
    return
if not cond2:
    # 이상처리(에러 로그 출력 같은)
    return
# 정상처리
    ... ...
    ... ...
    ... ...

깊은 인덴트가 사라지고 로직이 심플해진다

bool 타입 처리에 괜한 분기를 만들지 않는다

def is_correct_answer() -> bool:
    if cond1:
        return True
    else:
        return False
def is_correct_answer() -> bool:
    return cond1

하고 싶은 것은 1행으로.

긴 조건은 변수로

if long_long_long_long_long_cond1 and long_long_long_long_long_cond2:
    do_something()
cond1 = long_long_long_long_long_cond1
cond2 = long_long_long_long_long_cond2
if cond1 and cond2:
    do_something()

긴 조건을 나열하면 가독성이 떨어집니다.

변수명 cond1, cond2에 의미있는 이름을 부여하면 더욱 좋다.

리스트를 나눌경우

age_list = [20, 21, 22]
age1 = age_list[0]
age2 = age_list[1]
age3 = age_list[2]
age_list = [20, 21, 22]
age1, age2, age3 = age_list

dict에서 지정 키 값 얻기

if "name" in student_dict:
    name = student_dict["name"]
else:
    name = ""
name = student_dict.get("name", "")

파이널은 컨텍스트 매니저(with문)

try:
    f = open("test.txt", "r")
except Exception as e:
    ... ...
else:
    data = f.read()
    f.close()
with open("test.txt", "r") as f:
    data = f.read()

with문이 close까지 해준다.

일시적인 작업 디렉토리가 필요하다면

import os
import shutil

temp_dir = "temporary_dir"
os.makedirs(temp_dir, exist_ok=True)  # 디렉토리 만들기
do_something()
shutil.rmtree(temp_dir)  # 디렉토리 삭제
import tempfile

with tempfile.TemporaryDirectory() as temp_dir:
    do_something()

디렉토리 삭제까지 해준다

부모클래스 자료형까지 확인하고 싶다면

class Parent:
    pass

class Child(Parent):
    pass

item = Child()
if type(item) is Child or type(item) is Parent:
    do_something()
if isinstance(item, Parent):
    do_something()

맺으며

너무 자잘해서 와닿지 않은 코드리뷰였습니다.

더 좋은 작성 방법도 존재할 수 있으므로, 어디까지나 참조로