ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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란?

    1. Clean Code는 함수, 클래스 혹은 모듈이 한 가지에 집중해야 하고 잘 해야 한다.
    2. Clean Code는 읽기 쉬워야 한다.
    3. Clean Code는 디버그하기 쉬워야 한다.
    4. Clean Code는 유지 보수가 쉽다.
    5. 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)을 따라야 한다.

    반응형

    댓글

Designed by Tistory.