파이썬 코드를 작성하다 보면, 아래와 같이 함수 이름을 고민할 경우가 있다. 또 들여쓰기를 할 때 tab을 사용할 것인지, 혹은 스페이스를 4번 사용할 것인 지를 고민하는 경우가 있다. 이러한 경우를 위해 파이썬 공식 홈페이지에서는 PEP8이라는 파이썬 코드 스타일 가이드를 제공하고 있다. 본 포스트는 파이썬 코드 스타일 가이드를 정리하여, 추후 코드 작성에서 올바른 스타일로 코드를 작성하고자 한다.
#변수 명의 다양한 스타일
var_name
varName
VarName
varname
들여쓰기
- 들여쓰기는 4개의 스페이스를 사용할 것
- 첫번째 줄에 인자가 있으면 괄호에 맞추어 수직정렬을 할 것
- 첫번째 줄에 인자가 없으면 추가로 들여쓰기를 하여 아랫줄과 구분할 것
[옳은 예]
#괄호에 맞춰서 정렬을 하는 경우
foo = long_function_name(var_one, var_two,
var_three, var_four)
#아랫줄과 구분을 위해 들여쓰기를 추가하는 경우
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
#들여쓰기를 추가하여 함수 호출이 끝나지 않았다는 것을 알림
foo = long_function_name(
var_one, var_two,
var_three, var_four)
[틀린 예]
#수직정렬을 하지 않을 경우, 인자들을 첫번째 라인(함수 명과 같은 줄)에 사용하면 안됨
foo = long_function_name(var_one, var_two,
var_three, var_four)
#인자들을 들여쓰기 하지 않아서 아랫줄과 구분이 되지 않음
def long_function_name(
var_one, var_two, var_three,
var_four):
print(var_one)
if문
- if는 두글자이므로 if와 ( 사이에 스페이스를 하나 두면 스페이스 4개와 비슷한 효과가 있을 것
- if문에 대해서는 PEP가 큰 권고사항을 주고 있지는 않으므로, 아래와 같은 예제처럼 코드를 작성하면 될 것
# 추가적인 들여쓰기가 없음.
if (this_is_one_thing and
that_is_another_thing):
do_something()
#if문 끝에 주석을 추가하여 아래 행과 구분이 가도록 할 것.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()
#들여쓰기를 추가하여 아래 행과 구분되도록 할 것.
if (this_is_one_thing
and that_is_another_thing):
do_something()
괄호를 열고 닫는 경우
- 괄호를 닫는 경우에는 닫는 괄호 마지막 줄에 맞추거나 닫는 괄호에 공백을 주지 않아도 됨
#닫는 괄호 마지막 줄에 들여쓰기를 맞추는 경우
my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_argument(
'a', 'b', 'c',
'd', 'e', 'f',
)
#닫는 괄호에 공백을 주지 않는 경우
my_list=[
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
탭 vs 스페이스?
- 스페이스를 사용하는 것이 권장됨
- 다만 기존의 코드가 탭을 사용했다면 탭을 사용할 것
- 단 탭과 스페이스를 섞어서 쓰지 말 것
한 줄에 최대로 사용할 수 있는 글자 수
- 한줄에는 최돼 79글자만을 사용할 것이 권장됨
- 79글자가 넘어가는 경우에는 "\"(백슬래쉬)를 사용하면 됨
줄 바뀜 시 연산자 위치
- 줄이 너무 길어서 줄을 바꾸어야 할 때, 연산자를 바꾸기 전에 사용할 지 후에 사용할 지에 대해 고민이 필요하다.
- 기존에는 줄을 바꾸기 전에 연산자를 기입하였지만, 파이썬에서는 가독성을 위하여 줄을 바꾼 후 연산자를 기입하는 것을 권장한다.
- 아래는 줄 바뀜 시 연산자를 위치시키는 예제이다.
[옳은 예]
#연산자를 줄 바꾼 후에 사용
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
[틀린 예]
#연산자를 줄 바꾸기 전에 사용
income = (gross_wages +
taxable_interest +
(dividends - qualified_dividends) -
ira_deduction -
student_loan_interest)
공백에 관한 것
- 최고 단계의 함수나 클래스를 정의하면 2줄의 공백을 넣도록 한다.
- 클래스 안의 메서드를 정의하면 1줄의 공백을 넣도록 한다.
- 추가적인 공백은 함수들의 그룹을 구분할 때 유용하게 사용 될 수 있다.
class TestClass():
def test_action(self, content):
pass
def test_program(self, content):
pass
class ValidateClass():
def validate_action(self, content):
pass
def validate_program(self, content):
pass
파일 인코딩
- 파이썬의 코드는 UTF-8방식을 따르도록 한다.
import
- import문을 사용할 때에는 줄을 바꿔서 사용하도록 한다.
- import문은 항상 코드의 위쪽에 위치하도록 한다.
- import는 아래의 순서대로 그룹지어서 사용하도록 한다.
- Standard library imports
- Related third party imports
- Local application/library specific imports
(각 그룹 사이에는 공백을 두는 것을 추천한다.)
[옳은 예]
import os
import sys
[틀린 예]
import sys,os
혹은 아래의 경우에는 괜찮다.
[옳은 예]
from subprocess import Popen, PIPE
- ablsolute import를 하는 것을 추천한다. 이는 코드의 가독성을 높이고, 버그를 줄이기 때문이다.
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
- 다만 아래와 같이 relative import가 간결한 표현일 경우에는 허용한다.
from . import sibling
from .sibling import example
- 모듈 안의 클래스를 import할 때에는 아래와 같이 사용할 수 있다.
from myclass import MyClass
from foo.bar.yourclass import YourClass
- class 이름때문에 충돌이 발생할 경우 아래와 같이 import 하도록 한다
import myclass
import foo.bar.yourclass
- 단 wildcard(*) import는 피하도록 한다.
- 이는 가독성을 해치고, 더 나아가서 automated tools를 혼란스럽게 하기 때문이다.
Module Level Dunder Names
__all__, __author__, __version__과 같은 것들을 dunder Name이라고 부른다. 이 것들은 모듈 주석과 import 사이에 위치하여야 한다. 단, from __future__는 모듈 주석 바로 뒤에 위치시키도록 한다.
"""This is the example module.
This module does stuff.
"""
from __future__ import barry_as_FLUFL
__all__ = ['a', 'b', 'c']
__version__ = '0.1'
__author__ = 'Cardinal Biggles'
import os
import sys
문자열 따옴표
- 파이썬에서 문자열을 생성할 때에는 따옴표나 쌍따옴표를 사용하면 된다. 두 기호간의 구분은 없다.
공백에 관한 것
- 괄호 안에 사용하는 공백은 유의하여야 한다.
[옳은 예]
spam(ham[1], {egg: 2})
[틀린 예]
spam( ham [ 1 ], { egg: 2 } )
- 쉼표를 기입하고 괄호를 닫을 때는 그 사이에 공백을 두면 안된다.
[옳은 예]
foo = (0,)
[틀린 예]
bar = (0, )
- 콤마, 세미콜론, 혹은 콜론을 기입하기 전에 공백을 두면 안된다.
[옳은 예]
if x == 4: print x, y; x, y = y, x
[틀린 예]
if x == 4 : print x , y ; x , y = y , x
- 하지만 콜론과 연산자가 함께 사용될 경우에는, 또 콜론의 연산우선순위가 낮을 경우에는 콜론에 공백을 둘 수 있다.
[옳은 예]
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]
[틀린 예]
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]
- 여는 괄호 앞에는 공백을 두지 않는다.
[옳은 예]
spam(1)
dct['key'] = 1st[index]
[틀린 예]
spam (1)
dct ['key'] = 1st [index]
- '=' 기호를 수직정렬 시키기 위해 큰 공백을 두는 것은 좋지 않다.
[옳은 예]
x = 1
y = 2
long_variable = 3
[나쁜 예]
x = 1
y = 2
long_variable = 3
기타 사항
- 아래와 같은 연산자를 사용할 때는 한 칸씩 공백을 두도록 한다.
(=, +=, -=, ==, <, >, !=, <>, <=, >=, in, not in, is, is not, and, or, not) - 다른 우선순위의 연산자를 사용할 경우에는 우선순위가 낮은 연산자 사이에 공백을 두도록 한다.
[옳은 예]
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
[나쁜 예]
i=i+1
submitted +=1
x = x * 2 - 1
c = (a + b) * ( a - b)
- 함수 사용시에는 colon 뒤에는 공백을 넣고, -> 표현 사이에는 공백을 넣어야 한다.
[옳은 예]
def munge(input: AnyStr):
def munge() -> PosInt:
[나쁜 예]
def munge(input:AnyStr):
def munge()->PosInt
- 함수 사용에서 '=' 기호를 사용해서 keyword argument를 indication할 때에는 공백을 쓰지 않도록 한다.
[옳은 예]
def complex(real, imag=0.0):
return magic(r=real, i=imag)
[나쁜 예]
def complex(real, imag = 0.0):
return magic(r = real, i = imag)
- 함수 argument annotation 중 '=' 기호를 default value를 나타낼때는 공백을 두도록 한다.
[옳은 예]
def munge(sep: AnyStr = None):
def munge(input: AnyStr, sep: AnyStr = None, limit=1000):
[나쁜 예]
def munge(input: AnyStr=None):
def munge(input: AnyStr, limit = 1000)
- 또 여러개의 명령어를 하나의 줄에 작성하는 것은 추천하지 않는다.
- 단, if/for/while 문을 간결하게 한줄로 작성이 가능한 경우에는, 사용하여도 무방하지만 권장하지는 않는다.
[옳은 예]
if foo == 'blah':
do_blah_thing()
do_one()
do_two()
do_three()
[나쁜 예]
if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three();
Trailing commas(문자열 뒤에 기입하는 쉼표)
- Trailing comma를 사용하는 것은 자유롭지만, 1개의 요소만 존재하는 튜플을 사용할 경우에는 꼭 넣도록 한다. 또 튜플임을 알 수 있도록 괄호를 작성하는 것이 좋다.
[좋은 예]
FILES = ('setup.cfg',)
[나쁜 예]
FILES = 'setup.cfg',
- 또 추후 버전이 업그레이드 됨에 따라서 요소가 추가될 수 있다는 것을 알리기 위해서 trailing comma를 넣는 것이 좋다.
- 이 때에는 각 요소를 각각의 줄에 위치시키고, 닫는 괄호 역시 마지막 요소의 아래 행에 위치해야 한다.
[좋은 예]
# Correct:
FILES = [
'setup.cfg',
'tox.ini',
]
initialize(FILES,
error=True,
)
[나쁜 예]
FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
함수, 변수, 클래스 등의 이름에 대한 규칙
- 너무나 많은 패키지가 각각의 명명 규칙을 갖고있지만, PEP8에서 추천하는 명명규칙이 따로 존재한다.
- 따라서 새로 진행하는 프로젝트나 모듈 작성에서는 아래와 같은 규칙을 따를 것을 권장한다.
b (single lowercase letter)
B (single uppercase letter)
lowercase
lower_case_with_underscores
UPPERCASE
UPPER_CASE_WITH_UNDERSCORES
CapitalizedWord
mixedCase (첫 글자가 대문자가 아님)
Capitalized_Word_with_Underscores (ugly!)
- _single_leading_underscore는 내부적으로 사용하는 변수이다. 이 변수는 import * 시에 로딩되지 않는다.
- single_trailing_underscore_는 파이썬 키워드와 충돌하는 것을 막기 위해 사용된다.
[예]
tkinter.Toplevel(master, class_='ClassName')
- __double_leading_underscore: class attribute를 명명할 때 사용된다(FooBar 클래스 내부의 boo는 FooBAR__boo가 됨).
- __double_leading_and_trailing_underscore__는 magic 객체라고 불리우며, __init__, __import__, __file__등이 있다.
명명시에 피해야 할 문자
- i(lowercase letter el), O(uppercase letter oh), I(uppercase letter eye)는 사용하지 않도록 한다.
패키지와 모듈 이름
- 모듈은 짧고 모두 소문자여야 한다.
- 언더스코어는 가독성을 향상시킬 때만 사용 가능
- C/C++ 모듈의 이름 앞에는 언더스코어가 붙어야 한다 (예, _socket)
클래스 이름
- 클래스 이름은 CapWords로 지어야 한다.
예외 이름
- 예외는 클래스여야 하기 때문에 클래스 이름 작성 규칙을 따른다.
- 단 Error 접미사를 붙이도록 한다.
함수 및 변수 이름
- 함수이름은 언더스코어로 구분된 소문자(lower_case_with_underscores)를 사용하도록 한다.
- 변수 이름은 함수 이름 명명 규칙을 따르도록 한다.
- 이전버전에서 mixedCase를 사용한 경우에는 mixedCase를 따르도록 한다.
전역 변수 이름
- 전역변수 이름은 함수 명명 규칙을 따른다.
함수와 메서드 인자
- 항상 self가 인스턴스 메서드의 첫번째 인자가 되어야 한다.
- 항상 cls가 클래스 메서드의 첫번째 인자가 되어야 한다.
- 함수 인자가 파이썬 키워드와 충돌할 경우 single_trailing_underscore_ 를 따르도록 한다.
(e.g. class_를 사용하는 것이 clss를 사용하는 것보다 낫다)
메서드 이름과 인스턴스 변수
- 언더스코어로 구분된 소문자(lower_case_with_underscores)를 사용하도록 한다.
- non-public 메서드와 인스턴스 변수에는 _single_leading_underscore를 적용한다.
- 하위 클래스와 이름 충돌을 피하기 위해서 파이썬의 맹글링 규칙에 따라 __double_leading_underscore 를 사용한다.
상수
- 상수는 대문자로 작성한다(e.g. MAX_OVERFLOW, TOTAL).
'python' 카테고리의 다른 글
전문가를 위한 파이썬 책 구매 (0) | 2022.07.21 |
---|---|
파이썬 기반의 멀티프로세싱 (0) | 2021.12.15 |
closure & decorator (0) | 2021.12.15 |
병렬처리 특성 비교, 그리고 파이썬 기반의 멀티쓰레딩 (0) | 2021.12.06 |
python 기초 문법 및 여러가지 알아두면 좋을 것들 (0) | 2021.12.06 |