본문 바로가기
Python

[Python] - 파이썬 pep8 코드 스타일

by nam_ji 2024. 9. 26.

파이썬 코드 스타일 pep8 가이드

개요

  • pep8은 파이썬 문서에서 제공하는 코딩 스타일 가이드로 일관된 파이썬 코드 작성을 위한 가이드입니다. 무조건적으로 지켜야 하는 내용은 아니지만 별도의 이유와 준수하는 코딩스타일이 없다면 해당 내용을 지켜서 개발하는 것이 나쁠 것은 없어 보입니다.

Code lay-out

1. 들여쓰기

  • 각 들여쓰기 단계마다 4개의 스페이스를 사용합니다.
  • 연속적인 라인은 괄호들 ((), {}, []) 안의 원소들을 수직으로 정렬하거나, hanging indent를 적용하여 정렬해야 합니다.
    • foo = some_function(var1, var2,
      					var3, var4
      # 여는 괄호 다음에 줄을 바꾸지 않고 매개변수를 타이핑 했다면
      # 줄을 바꿀때처음 매개변수의 위치에 맞춥니다.
      
      foo = some_function(
          var1, var2,
          var3, var4)
      # 첫 원소부터 줄을 바꿀때는 들여쓰기를 하나 추가하고
      # 그 다음줄로 바꿀때도 첫줄에 맞춰서 들여쓰기(hangling indents)
      # 이때는 꼭 4스페이스 들여쓰기를 할 필요는 없습니다.
      
      def some_function(
              var1, var2,
              var3, var4):
          print(var1)
      # 다음 구문과의 구별을 위해 추가적인 들여쓰기를 사용합니다.
  • if문의 경우 if(condition) 형태로 시작하면 줄을 바굴 때 자연스럽게 4 space 들여쓰기가 되지만 if문 내부의 코드와 구분이 어려워 질 수 있습니다.
    • #별도의 기준은 없고 알아서 선택합니다.
      
      #별도의 들여쓰기 없이 사용합니다.
      if (condition1 and
      	condition2):
          some_function()
      
      #설명하는 주석을 남겨서 구별합니다.
      if (condition1 and
      	condition2):
          #some comments
          some_function()
          
      #여러줄에 걸쳐 추가적인 들여쓰기 사용합니다.
      if (condition1
      		and condition2):
          some_function()
  • 괄호를 닫을때 괄호안의 첫 원소의 위치에 맞춰서 or 구문의 첫 문자를 기준으로 닫을 수 있습니다.
    • my_list = [
      	1, 2, 3,
          ]
          
      my_list = [
      	1, 2, 3,
      ]

2. tab or space

  • 기본적으로 4space가 권장됩니다.
  • 단, 이미 탭으로 코드가 작성 되었다면 일관성을 맞춰서 탭을 사용합니다.
  • 단, 두 방법의 혼용은 안됩니다.

3. 한 줄의 최대 길이

  • 모든 줄은 한 줄 최대 79개의 문자를 권장합니다.
  • 긴 텍스트 블록이나 주석은 최대 72문자를 권장.
  • 긴 줄은 백슬래시( \ )를 사용하여 명시적으로 구분해줄 수 있다. 3.10 이전의 python에서는 with가 implicit continuation이 적용되지 않아 필수적으로 사용해야 한다.

4. 이항 연산자에서의 줄바꿈 위치

  • 전통적으로 이항 연산자 뒤에서의 줄바꿈이 대세지만 연산자들의 위치가 열 기준으로 봤을때 흩어져있고 피연산자를 한번에 보기 힘듭니다.
  • 완전히 새로운 코드라면 이항 연산자 이전에서 줄바꿈을 하는 것을 권장합니다.
    • # 수학적인 표기법이 가독성이 더 좋긴 합니다.
      result = (var1
                + var2
                - var3
                * var4)

5. 공백 줄

  • 최상위 레벨 함수와 클래스 정의 앞뒤로 2개의 공백줄을 적용합니다.
  • 클래스 내의 메소드 정의 앞뒤로는 1개의 공백줄을 적용합니다.
  • 함수들의 그룹을 확실하게 구분하기 위해 추가적인 공백줄 적용 가능합니다.
  • 함수 내에서는 논리적 구조에 따라 적절하게 사용합니다.

6. 소스 파일 인코딩

  • 배포코드는 항상 UTF-8을 사용합니다.
  • 모든 식별자들은 ASCII로 구성되어야 하고 일부 예외를 제외하면 영어를 사용 해야합니다.

7. import

  • import는 분리해서 사용합니다.
    • import os
      import sys
      # import os, sys 는 권장하지 않습니다.
      
      from subprocess import Popen, PIPE
      # 이런 형태는 권장합니다.
  • import는 항상 파일의 맨 위에 놓입니다. 정확히는 모듈 주석과 독스트링 바로 다음, 모듈 전역과 상수 바로 전에 위치합니다.
  • import 순서는 표준 라이브러리 > 관련 서드 파티 > 로컬 어플리케이션/라이브러리 순서로 작성합니다.
  • 절대경로를 사용하는 것을 권장합니다. 특히 표준 라이브러리는 절대경로를 사용합니다.
  • 클래스를 갖고 있는 모듈에서 클래스를 가져올때 다음과 같이 작성합니다. 이때 현재 사용하는 변수와 충돌한다면 명시적으로 작성합니다.
    • from myclass import MyClass
      from foo.bar.yourclass import YourClass
      
      import myclass
      import foo.bar.yourclass
      # MyClass 와 YourClass를 현재 코드에서 사용 중이라면 위와 같이 import 하고
      # myclass.MyClass, foo.bar.yourclass.YourClass로 사용합니다.
  • 일부 경우를 제외하고는 다음과 같은 와일드카드 사용은 권장하지 않습니다.
    • from myclass import *

8. 모듈 수준의 Dunder name

  • __all__ 이나 __author__, __version__ 같은 변수들은 모듈의 docstring 다음, from _ import_ 형태의 import 다음, import 이전에 위치합니다.

문자열 따옴표

  • 파이썬에서는 두 종류 모두 사용이 가능하니 특정 따옴표만 사용하라기 보다는 일관성 있게만 사용하는 것을 추천합니다.
  • 문자열 내에서 따옴표를 사용할때는 \을 쓰는것 보다는 그냥 다르게 사용하는 것을 추천합니다.
  • 문자열 블록의 경우는 쌍따옴표를 사용하는 것이 원칙입니다.

expression과 statement내의 공백

  • 괄호의 바로 안족에서는 space를 쓰지 않습니다.
  • 마지막이 쉼표로 끝나는 후행 쉼표에서는 space를 쓰지 않습니다.
    • foo = (0,)
      #foo = ( 0, ) -> 잘못된 표현입니다.
  • 콤마, 세미콜론, 콜론의 다음에 space입니다.
  • 슬라이싱에 사용하는 콜론은 앞뒤로 동일하게만 적용합니다.
    • if x == 4: print(x,y); x, y = y, x
      
      my_list[1:9]
      my_list[: 1 : 2]
      my_list[:: 3]
      my_list[a + b : b : c]
      my_list[a+b : b+c]
      my_list[a+b:b+c]
      #처럼 일관성 있게 앞뒤로 공백을 적용하던가 적용하지 않던가 결정합니다.
  • 함수 호출시의 소괄호 앞, 인덱싱의 대괄호 앞에는 space가 있으면 안됩니다.
  • 할당연산자(=) 앞뒤로는 하나의 space입니다.
  • 쓸데없는 후행 공백은 권장 하지 않습니다.
  • 항상 이항 연산자들은 공백으로 둘러 싸야 합니다.
  • 서로다른 우선순위를 가진 이항 연산자를 사용할 경우 제일 낮은 우선순위를 가진 이항 연산자에 공백을 사용하는 것을 추천합니다.
    • i = i + 1
      i += 1
      y = x*2 + 1
      c = (a-b) * (b-c)
  • 함수 annotation은 콜론과 동일하게, ->의 경우 앞뒤로 space를 적용합니다.
    • def some_function(input: int) -> int:
      	...
  • =가 함수정의에서 annotation 없이 default 값을 가리키거나 함수 사용시 키워드를 가리킬때는 space를 사용하지 않습니다.
  • 함수 annotation에서 사용될 경우 앞뒤로 space 사용합니다.
    • def some_function(a, b=1):
      	...
          
      def some_function(a, b: int = 1):
      	...
  • ;를 이용한 한줄에 여러 문을 적는 복합문은 권장되지 않습니다.
  • 특히 구별이 힘들게 여러 조건, 반복문등을 한줄에 쓰는 것은 하면 안됩니다.

후행쉼표

  • 기본적으로 선택사항. 단 한 개의 요소를 가지는 튜플을 만들 때는 필수 사항입니다.
    • my_tuple = (1,)
  • 대체로 언젠가 확장될 일이 있는 리스트 등에 사용하는 것이 유용합니다.

주석

  • 코드를 변경할 때마다 항상 갱신하는 것을 잊으면 안됩니다.
  • 주석은 완전한 문장으로 쓰여져야 합니다. 영문의 경우 첫 문자는 대문자로 시작합니다. 단 식별자의 경우 식별자 그대로 사용합니다.
  • 블록 주석은 하나 이상의 단락으로 구성되며 마침표로 끝나야 합니다.
  • 여러 문장으로 된 주석은 문장의 마지막에 공백 2개를 사용합니다. 마지막줄은 제외합니다.

1. 블럭 주석

  • 일반적으로 그 뒤에 오는 일부 코드에 적용되며 해당 코드와 동일한 레벨로 들여쓰기되어야 합니다. 각 줄은 #과 하나의 공백으로 시작합니다.

2. 인라인 주석

  • 꼭 필요한 경우에만 사용합니다.
  • 최소 두칸 이상의 공백으로 구별되어야 하며 단순 상태를 나타내기 보다는 무엇을 위한 동작인지를 적는 것이 유용합니다.

3. docstring

  • PEP257에 규칙이 존재합니다.
  • 최대한 모든 모듈, 함수, 클래스, 메소드들에 대한 설명을 남겨 놓습니다.

명명법

  • 파이썬의 명명법은 꽤 혼재되어 있습니다.
  • 기존 코드들은 일관성을 지키며 적용하고 새로운 코드들은 다음과 같은 방법을 준수합니다.

1. 여러가지 스타일

  • b : 단순 소문자
  • B : 단순 대문자
  • lowercase : 소문자
  • UPPERCASE : 대문자
  • snake_case : _를 사용한 형태
  • CaptializedWords : PascalCase이라고도 불리는 형태로 모든 첫글자를 대문자로. 주로 함수와 클래스 정의시 많이 사용되는 형태. 원래 약어인 단어는 모두 대문자로 쓰는게 보기 편합니다.
  • camelCase : 첫단어의 첫글자만 소문자고 다음단어부터는 구분을 위해 대문자를 첫글자로 사용하는 형태. PascalCase와 마찬가지로 사용되며 두개를 혼용하여 사용하기도 한다.
  • _single_leading_underscore : 약한 내부사용 지표로 _를 앞에 붙인 형태. 해당 형태로 지어진 변수나 함수 등은 해당 모듈의 내부에서만 사용한다는 의미로 이해하면 됩니다.
  • single_trailing_underscore_ : 파이썬 예약어와 겹치는 변수명을 사용하고자 할때 마지막에 _를 붙여서 중복을 피합니다.
  • __double_leading_underscore : name mangling에 사용. 변수명을 뭉갠다는 의미로 클래스 내에서 유사 private 접근자 처럼 사용하거나, 상속받은 메소드의 오버라이딩을 방지할때 사용합니다. 실제로 외부에서 접근하지 못하는게 아니라 _ClassName__attributeName 형태로 변경되어 저장됩니다.

명명법 규정 사항

1. 피해야할 이름

  • ㅣ소문자 L,O 대문자 O,I 대문자 i 는 절대 단독으로 변수명으로 사용해서는 안됩니다.
  • 표준 라이브러리에서 사용되는 식별자는 반드시 ASCII 호환성을 따라야 합니다.

2. 패키지명과 모듈명

  • 모듈명은 모두 소문자를 사용하여 짧게 지어야 합니다. 가독성을 위해 _를 사용할 수 있습니다.
  • 패키지명 또한 모두 소문자를 사용하여 짧게 지어야 합니다. 모듈명과는 다르게 _ 사용을 권장하지 않습니다.
  • C/C++ 모듈들은 첫글자를 밑줄 이름으로 짓습니다.

3. 클래스명

  • 일반적으로 CapWords형태를 사용합니다.

4. 타입 변수명

  • PEP484에 소개되는 type variable은 CapWords형태로 짧게 짓습니다.
    • type annotation이나 typing 내장 패키지 를 사용하여 동적 타입의 단점을 보완할 때 사용하는 개념입니다.

5. 예외 명

  • 예외는 클래스이므로 클래스와 동일하게 적용합니다.
  • 실제 error와 같은 개념을 가진 예외일 경우 Error를 접두어로 사용합니다.

6. 전역변수명

  • 함수와 동일한 방법을 사용합니다
  • __all__을 통해 내보낼 변수를 지정하지 않을 경우 _를 앞에 붙여 사용하는 방법을 사용합니다.

7. 함수와 변수명

  • 함수는 소문자여야하며 가독성을 위해 밑줄로 구분해야 합니다. (snake_case)
  • 변수명도 동일합니다.
  • camelCase의 경우 이미 스타일이 존재하는 경우에 허용하여 사용합니다.

8. 함수와 메서드의 arguments

  • 항상 self를 인스턴스 메소드의 첫번째 인자로 사용합니다.
  • 항상 cls를 클래스 메소드의 첫번째 인자로 사용합니다.
  • 함수의 argument가 파이썬 예약어와 겹치면 후행 밑줄을 사용합니다.

9. 메서드명과 인스턴스 변수

  • 함수와 마찬가지로 소문자를 사용하고 가독성을 위해 밑줄로 구분합니다.
  • 첫글자 밑줄은 non-public을 나타내기위해 사용합니다.
  • 위에서 설명한것처럼 충돌을 피하기 위해 mangling을 사용합니다.

10. 상수

  • 모듈 수준에서 정의하며 일반적으로 대문자만 사용하고 밑줄로 구분합니다.

프로그래밍 권장 사항

  • 코드는 python의 다른 구현들에 해가 되지 않는 방향으로 작성되어야 합니다.
  • None같은 싱글톤과의 비교는 항상is, is not으로 이루어져야 합니다.
  • if x를 사용할때는 정말로 if x is not None의 의미를 가져야 합니다.
  • if not을 not ... is 보다 더 사용하는게 가독성상으로 좋습니다.
  • 식별자에 직접적으로 함수를 할당하는 것 보다는 def를 사용하여 별도로 정의하는게 좋습니다.
  • 예외는 Exception으로 부터 상속받습니다.
  • 예외를 포착할때 단순히 except:를 사용하기 보다는 정확한 특정 예외를 언급합니다. 생 except는 SystemExit와 KeyboardInterrupt 예외를 포착하여 ctrl + c 를 통해 프로그램 중단을 어렵게 만들 수 있습니다.
  • 모든 예외를 포착하고 싶다면 except Exception:을 사용합니다.
  • try:문은 최대한 간략하게 필수적인 코드만 넣어야 합니다.
  • return 문의 일관성을 지켜야 합니다. 모든 반환문은 expression을 반환 하거나 어떤 것도 반환하지 않아야 합니다.
    • def foo(x):
      	if x >= 0:
          	return math.sqrt(x)
          else:
          	return None
              # None이 없어도 동작과는 상관 없지만 일관성을 위해 사용합니다.
  • 접두사, 접미사를 확인할때는 슬라이싱 보다는 ''.startwith(), ''.endwith()를 사용합니다.
  • 오브젝트 타입비교는 isinstance(obj,type)을 사용합니다.
  • 시퀀스에 대해서는 빈 시퀀스가 false인 점을 활용합니다.
    • if not seq:
      if seq:
      
      #굳이 다음과 같은 형태로 사용하지 않습니다.
      if len(seq):
  • boolean 값을 ==를 사용하여 True, False와 비교하지 않습니다.
  • finally: 내부에서의 return, break, continue의 사용은 권장되지 않습니다.

PEP8 체크 모듈

설치

  • pip install pep8
    pep8 hello_world.py
  • 실행하면 단일 파일 또는 여러 파일들의 PEP8 위반 보고서를 얻을 수 있습니다.