파이써닉(Pythonic) 코드를 위한 가이드

Jaehyeong Kwon·2023년 2월 21일
0

1. PEP8 스타일 가이드 따르기

파이썬은 PEP8 (Python Enhancement Proposal) 이라는 코드 스타일 가이드 가 있습니다.

들어가면 매우 많은 양의 문서가 있습니다. 기초적인 공백, 들여쓰기, 문법 등을 어떻게 하면 좋을 지 상세하게 작성되어 있습니다.


2. 변수, 클래스 네이밍

변수와 클래스 이름은 가독성에 있어 매우 중요합니다. 자바스크립트에서 쓰이는 네이밍 룰과는 다른 부분이 있어 파이썬 스타일 네이밍을 숙지해두면 좋습니다.

1. 변수, 함수, 어트리뷰트는 snake_case를 사용합니다.

ex) total_users, get_total_users(),

2. 클래스는 PascalCase를 사용합니다.

ex) User(), Car()

3. 모듈 수준의 상수는 모든 글자를 대문자로 하여 snake_case를 사용합니다.

ex) OS_PATH, SQL_LIMIT

  • 보호해야하는 인스턴스 어트리뷰트는 밑 줄 한개(_)로 시작합니다.
  • private 인스턴스 어트리뷰트는 밑 줄 두개(__)로 시작합니다.

클린 코드에서 추천하는 좋은 변수 네이밍은 다음과 같습니다.

  1. 의도를 분명히 밝힐 수 있는 변수명

    1. 코드 편집기가 자동 지원을 잘 지원해서, 긴 변수 네이밍이 문제가 되지 않습니다.
    2. 길더라도 변수의 의미를 충분히 담을 수 있도록 한다.
  2. 예약어, 내장 함수들의 이름 사용을 지양하기
    다른 언어(java, c++) 과는 다르게 파이썬에서는 예약어와 내장 함수로 변수 이름을 지어도 오류가 발생하지 않습니다. 하지만 추후 문제가 생길 가능성이 있어 되도록 피해서 네이밍을 해야한다. (ex: map, zip, sort)

  3. 의미가 중복되는 네이밍 지양

    1. 어트리뷰트에서 맥락 상 자명한 부분을 한번 더 명시할 필요가 없다.
    class User():
    	user_name = "Stillav"
        user_age = 25
    class User():
    	name = "Stillav"
        age = 25

3. import 구성하기

파이썬에서는 다양한 라이브러리를 Import 하여 사용합니다. import를 잘 작성해야 코드를 이해하기 쉬워집니다.

  1. import 는 반드시 파일의 상단에 위치시키기

  2. 한 라인에는 하나의 import 만 하기

    import datetime, sys, math (X)
    
    import datetime (O)
    import sys
    import os
  3. 순서에 맞게 import 하기

    1. 표준 라이브러리, 서드파티, 직접 만든 모듈 순으로 섹션을 나눠 import합니다
    2. 세션 내에서도 비슷한 부류의 모듈끼리는 묶어서 작성합니다.
#표준 라이브러리
import math
import sys
import os

#서드파티
import numpy as np
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

#직접 만든 모듈
from dataset import Dataset
from dataloader import DataLoader
  1. import 는 상대 경로를 지양하고 절대 경로를 이용하기
    1. 절대 경로가 복잡할 경우, 명시적 상대 경로 사용 가능합니다.

4. f-string 사용하기

파이썬 내에서는 여러가지 방법으로 문자열을 포맷팅할 수 있습니다.
1. C style formatting (%)
2. str.format()
3. f-string
최근에는 3번째 방법인 f-string 기법을 주로 이용하고 있습니다.

# C style formatting 
print("%d %d일" % (month, day))

# str.format()
print("{}월 {}일".format(month, day))

# f-string
print(f"{month}{day}일")

5. List Comprehension

파이썬에서 다른 시퀀스나 이터러블에서 새 리스트를 만들어야하는 경우가 있습니다.
이때 List Comprehension 을 사용하면 속도간결함 모두 잡을 수 있습니다.

# 예시) 모든 원소를 제곱한 리스트를 얻고 싶다 
a = [2,4,6,8]

# 기존 방식 
squares = list()

for x in a:
	squares.append(x**2)
    
# List Comprehension
squares = [x**2 for x in a]

# List Comprehension with if statement 
squares = [x**2 for x in a if x % 2 == 0] 

# else 문 또한 이용할 수 있음 

# 반복문이 복잡할 때 List Comprehension의 사용을 고집할 필요는 없다. 
square_matrix = [[x**2 for x in row in x % 2 == 0] for row in matrix if len(row) % 2 == 0]

6. Enumerate

enumerate 를 사용하면 이터레이터나 시퀀스에서 인덱스 정보를 손쉽게 순회할 수 있습니다.

a = [2,4,6,8]

# 기존 방식 
for i in range(len(a)):
	print(i, a[i])
    
# Enumerate
for i, num in enumerate(a):
	print(i, num)

7. Zip

동시에 두 리스트를 순회해야할 때 zip 이 유용하게 사용됩니다.

names = ['jaehyeong', 'jonghyun', 'ziho']
scores = [92, 94, 85] 

# 기존 방식 
for i in range(len(names)):
	print(names[i], scores[i])
    
# Zip 활용
for name, score in zip(names, scores):
	print(name, score)

두 리스트의 길이가 같지 않다면 짧은 리스트의 원소만큼만 순회합니다.
iterator 객체를 순회하는데 유리합니다.


8. Packing, Unpacking

가변 개수의 함수 인자를 사용할 때 매우 유용합니다.
코드에서 *이 의미하는 것이 packing 인지 unpacking인지 헷갈리는 경우가 있습니다.
이때는 함수를 정의하는지, 호출하는지로 보면 쉽게 구분할 수 있습니다.

  • (*) 별 한개 : list, tuple 의 인자
  • (**) 별 두개 : dictionary의 인자 (키워드 인자)
  • packing
    • 함수를 정의할 때 사용
# 가변 매개 변수의 이름은 자유롭게 지을 수 있지만, args와 kwargs를 사용합니다. 
def example(*args, **kwargs):
	print(args)
   	# (1,2)
    print(kwargs)
    # {'a': 10, 'b': 20}
  • unpacking
    - 함수를 호출할 때 사용
def add(a,b):
	return a + b 
    
add(*[1,2])
add(**{'a': 1, 'b':2})

9. 예외 처리

견고한 시스템을 위해서 예외 처리는 매우 중요합니다.
파이썬에서는 예외처리를 위해 try, except, else, finally 를 활용합니다.

else, finally의 경우에는 필요한 경우에만 사용합니다.

  • else
    - try 블록에서 에러가 발생하지않으면 해당 구간을 수행합니다.
  • finally
    - 에러 발생 여부에 상관없이 해당 분기를 수행합니다.
    • 스트림이나 리소스를 반환 혹은 종료 해야 할때 유용합니다.
      def example():
      	try:
          	f = open('hi.txt')
          except FileNotFoundError as e: # FileNotFoundError가 발생하면 해당 분기 실행 
          ... 
      				else: # try 블록에서 에러가 발생하지 않으면 해당 분기 실행
          ...
          finally: # 에러 발생과 상관없이 일어나는 블록
          	f.close()
              

10. Generator

C 언어의 꽃이 포인터라는 말이 있듯이 파이썬의 꽃은 제너레이터라고도 불립니다.

제너레이터를 사용하면 성능 향상, 메모리 사용 줄이기, 가독성 향상의 효과가 있습니다.
제너레이터란 iterator 를 생성해주는 함수, 함수 안에 yield 키워드를 사용합니다.


이러한 방식을 최대로 사용하면 진정한 pythoner에 한 걸음 다가갈 수 있을 거라 생각합니다.

profile
나무와 같이 성장하는 사람

0개의 댓글