PEP8 원본
https://www.python.org/dev/peps/pep-0008/
PEP8 개요
PEP8은 파이썬 코드의 작성규칙(coding convention)에 대해 설명하는 문서이다.
귀도(파이썬 개발자)의 중요한 인사이트중 하나는 코드는 작성하는 것 보다 읽는 것이 더 쉬어야 된다는 것이다. 따라서 PEP8은 코드의 가독성을 향상시키는 것과 파이썬 코드의 작성법을 일관적으로 하는 것을 목적으로 한다.
많은 프로젝트에서 각자의 코딩 가이드라인을 사용하고 있다. 이렇게 명확한 코딩 가이드라인을 가지고 있는 프로젝트와 같은 경우, 어떤 갈등이 야기되는 상황에서 그 프로젝트의 가이드라인이 우선시 된다.
먼저 코드에서의 일관성은 매우 중요하며, 프로젝트 내에서의 일관성은 더욱더 중요하고, 하나의 모듈 혹은 함수안에서의 일관성은 가장 중요한 요소이다.
따라서, PEP8에 따라 코드를 작성함에 있어서 일관성이 지켜지지 않을 경우 독자의 판단에 따르도록 한다. 다시한번 말하지만 PEP8은 권장사항이지 절대적인 법칙은 아니다.
특히, PEP8을 준수하기 위해 이전 버전과의 호환성을 무시하지 말것을 권장한다.
아래 사항은 가이드라인을 준수하지 않아도 되는 대표적인 사례이다.
- PEP8에 따라 코드를 읽는 사람임에도 불구하고, 가이드라인을 적용하는 것이 코드의 가독성을 해칠 경우
- 과거에 PEP를 준수하지 않고 작성한 코드와의 일관성을 유지하는 경우.(PEP를 준수하여 코드를 수정할 있는 상황이라도 과거코드 스타일을 존중하자. ex. XP 스타일)
- 코드작성시기가 PEP8의 작성 시기보다 앞서며, 그리고 코드를 수정할 필요가 없을 경우
- 과거버전의 파이썬으로 작성된 코드가 PEP8를 준수할 경우 작성된 코드가 작동하지 않아 과거 버전과 호환될 필요가 있을 경우
코드 레이아웃
들여쓰기
들여쓰기 - 기본
○ 한번의 들여쓰기에 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 구문의 첫째 줄과 혼동을 일으킬 여지가 존재한다.
○ PEP8에서는 이 문제에 대해 명확한 입장을 제시하지는 않으나 다음 예제와 같은 몇 가지 옵션을 제시한다.
if 구문에 대한 몇 가지 예 :
# 추가적인 들여쓰기가 없는 경우
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()
# 경우에 따라 if문에 연산자가 추가될 경우 연산자 전 혹은 후에 줄바꿈을 할것인지에
# 대한 부분은 뒤에 연산자 부분 참고
들여쓰기 - 괄호(여러 줄)
○ 기본에서 설명한 것보다 상세하게 설명하면, 닫는 괄호의 경우 마지막 줄의 첫번째 요소 바로 아래 맞추어도 된다.
○ 혹은 공백 없이 라인의 가장 앞에 맞추어도 된다.
# 첫번째 요소 아래 맞추는 경우
my_list = [
1, 2, 3,
4, 5, 6,
]
result = some_function_that_takes_arguments(
'a', 'b', 'c',
'd', 'e', 'f',
)
# 라인의 가장 앞에 맞추는 경우
my_list = [
1, 2, 3,
4, 5, 6,
]
들여쓰기 - Tab과 스페이스
○ 스페이스가 선호되는 내어쓰기 방법이다.
○ 다만, 이미 과거에 작성된 코드에 적용되어 일관성을 유지할 필요가 있을 경우 탭을 사용해도 된다.
○ Python3의 경우 탭과 스페이스의 조합은 문법적 오류를 야기한다.
○ Python2의 경우 탭과 스페이스가 섞여있는 경우 탭이 스페이스로 변환되어진다.
▷ -t 옵션을 사용하여 Python 2 커맨드라인을 호출할 때, 스페이스와 탭을 섞어서 작성된 코드에 대해 경고가 뜬다.
▷ -tt 옵션을 사용하는 경우에서는 경고가 아니라 에러가 되며, 이 옵션이 추천된다.
한줄의 최대 길이
○ 한 줄의 최대 길이는 79 문자로 제한된다.
○ 닥스트링이나 주석과 같이 구조적 제한이 적은 긴 텍스트 블럭을 처리하기 위해선, 한줄의 최대 길이는 72로 제한되어야 한다.
기대효과
○ 사용되는 에디터의 윈도우 폭을 제한하여 여러 파일을 열어 겹쳐보는 것을 가능하게 한다.
○ 이는 인접한 열에 두 버전을 제공하는 코드 리뷰툴을 사용할 때 작업효율을 개선한다.
○ 대부분의 툴에서 기본 행바꿈은 코드의 가시적 구조를 파괴하여 이해하기 어렵게 만든다.
○ 폭이 80글자로 세팅되어있는 윈도우 에디터 툴에서, 심지어 라인의 줄바꿈을 자동으로 해주는 상황에서도, 최대 줄수를 제한하는 것은 기본 행바꿈에 의해 구조가 파괴되는 상황을 피하기 위함이다.
○ 몇몇의 웹 기반 툴은 동적인 자동 줄바꿈을 지원하지 않는다.
기타 사항
○ 특정 팀들 한줄의 길이가 긴 것을 강력하게 선호한다. 이런 팀들에 의해 유지되는 코드에 대해서는, 주석이나 닥스트링은 여전히 72글자를 사용한다는 범위 내에서 코드의 길이를 80글자에서 100글자로 증가시키는 것도 허용된다.
○ 파이썬의 표준라이브러리는 보수적이며, 79글자 이내로 제안하는 것을 요구한다.
(닥스트링과 주석은 72글자)
○ 백슬래시(혹은 \, 원단위)를 활용하는 것은 매우 적절하다. 예를들어 매우 길며 여러줄을 사용하는 with구문은 계속적으로 사용할 수 없는데, 이 경우 백슬래시가 적용 가능하다.
예제)
with open('/path/to/some/file/you/want/to/read') as file_1, \
open('/path/to/some/file/being/written', 'w') as file_2:
file_2.write(file_1.read())
(See the previous discussion on multiline if-statements for further thoughts on the indentation of such multiline with-statements.)
○ 다른 예로는 assert 구문이 있다
○ 연속되는 줄에서는 들여쓰기가 적절한지 확인하는 습관을 들이자.
이항연산자(binary operator)에서의 줄바꿈
○ 수십년동안 추천된 스타일은 이항연산자 후에 줄바꿈을 하는 것이었다.
○ 그러나 이것은 두가지 방법으로 가독성을 해칠 수 있다.
▷ 먼저 연산자는 스크린상에서 한열이 아니라 여러 열로 흩어지는 경향이 있다.
▷ 각각의 연산자는 피연산자 이후에 배치된다.
○ 아래 이러한 상황을 살펴볼 수 있는 예가 있다.
예시)
# No: operators sit far away from their operands
income = (gross_wages +
taxable_interest +
(dividends - qualified_dividends) -
ira_deduction -
student_loan_interest)
○ 가독성 문제를 해결하기 위해 수학자와 출판자들은 위의 예와 반대인 표기법 사용한다.
○ Donald Knuth는 그의 컴퓨터 타이핑세팅(Computers and Typesetting) 시리즈에서 전통적인 방법을 설명한다.
▷ “단락내의 수식들은 항상 이항연산자 이후에 줄바꿈이 되지만, 보여지는 수식은 항상 이항연산자 전에 줄바꿈이 된다."
○ 수학자들의 전통을 따르는 아래의 예는 결과적으로 가독성이 더 좋은 코드를 만든다.
예시)
# Yes: easy to match operators with operands
income = (gross_wages
+ taxable_interest
+ (dividends - qualified_dividends)
- ira_deduction
- student_loan_interest)
○ Python 코드에서는 지역적으로 일관적인 표기법이 있는한 이항연산자 이전 혹은 이후에 줄바꿈을 하는 것이 허락된다.
○ 새로 작성되는 코드에 대해서는 Knuth방식의 스타일이 추천된다.
빈줄
○ 가장 높은 위치에 있는 함수와 클래의 정의 사이에는 2개의 줄바꿈을 사용하도록 한다.
○ 클래스 내부의 메서드 정의는 위 아래로 줄바꿈을 사용하여 구분하도록 한다.
○ 추가적인 빈줄은 연관된 함수들의 그룹을 분리하는데 사용된다.
○ 줄바꿈은 한줄 짜리 묶음사이에서는 생략될 수 있다.
○ 함수내에 논리 섹션을 나타내기 위해 빈줄을 사용할 수 있으나, 적당히 사용하도록 한다.
Control-L(^L) 폼피드 문자
○ Python은 control-L(^L) 폼피드 문자를 공백으로 취급함. 많은 툴에서 이 문자를 페이지를 나눠주는 역할로 사용한다.
○ 그래서 몇몇 사용자는 이 문자를 페이지를 나누는데 사용한다.
○ 몇몇의 에디터들과 웹 기반 코드 뷰어들은 control-L문자를 폼피드로 인식하지 못하고 다른형태의 특수문자로 보여준다는 것을 참고하라.
소스파일 엔코딩
○ 핵심 파이썬 배포판의 코드는 항상 UTF-8를 사용하여야한다. (혹은 Python2에서는 ASCII)
○ ASCII(Python2) 혹은 UTF-8(Python3)을 사용하는 파일들은 엔코딩 선언을 해서는 안된다.
○ 표준라이브러리에서는 기본값이 아닌 엔코딩은 오직 테스트목적이나 주석 및 닥스트링에 코드작성자 이름(ASCII 글자가 아닐 경우)을 언급할 때만 사용되어야 한다.
○ 그외에는 \w, \u, \U 혹은 \N 확장키(escape)를 사용하는 것이 ASCII 데이터가 아닌 문자열을 포함하는 것에 대해 선호되는 방법이다.
○ 파이썬 3.0 혹은 그이후의 버전에서는, 표준라이브러리에 대해 아래에 설명하는 정책이 미리 규정된다. (PEP 3131 참고할 것)
▷ 파이썬 표준라이브러리에서 사용되는 모든 식별자(identifier)는 반드시 ASCII 식별자만 사용하여야 하며, 실현가능한 곳에서는 영어 글자만 사용하도록 한다. (많은 경우에서 축약형이나 기술적인 용어의 경우에는 영어로 안쓰이는 경우가 있다.)
▷ String 문자열과 주석은 반드시 ASCII를 사용하여야만 한다.
▷ 예외적인 경우로 (a)ASCII 특성이 아닌 것을 테스트할때, (b)작성자의 이름. 라틴 알파벳(latin-1, ISO/IEC 8859-1 character set) 기반의 이름이 아닌 작성자는 반드시 이름의 음역(transliteration)을 제공하여야 한다.
○ 전세계인이 참여하는 오픈소스 프로젝트에서는 이와 유사한 정책이 실행되고 있다.
Import
○ import는 행으로 구분되어 사용되어야 한다.
좋은 예 :
import os
import sys
나쁜 예 :
import sys, os
○ 아래의 경우는 사용해도 좋다.
from subprocess import Popen, PIPE
import의 위치 및 그룹화
○ import는 항상 파일의 가장 위쪽에 모듈의 주석과 닥스트링 뒤에, 모듈 전역번수나 상수 전에 위치 시키도록 한다.
○ import는 아래와 같이 그룹화 하도록 한다.
▷ 표준 라이브러리 import
▷ 관련된 서브파티 import
▷ 로컬 어플리케이션/자체라이브러리 import
▷ 위의 그룹 사이에는 빈 줄을 넣는 것이 좋다.
import의 사용
○ 만약 import 시스템이 부정확하게 설정된 경우(예: 패키지 내부의 디렉토리가 sys.path로 끝나는 경우), 위처럼 그룹화가 된다면 읽기 쉬워지며 수정이 용이해지므로(error메세지 확인이 용이해진다.), Absolute import가 권장된다.
import mypkg.sibling
from mypkg import sibling
from mypkg.sibling import example
○ 그러나, Absolute import를 사용하는 것이 쓸데없이 장황한 곳에서 복잡한 패키지 레이아웃을 다루고 있을때, Absolute import에 대해 Explicit relative import는 적용 가능한 대안이다.
from . import sibling
from .sibling import example
○ 표준 라이브러리 코드는 복잡한 패키지 래이아웃을 피해야하며 항상 absolute import를 사용하여야 한다.
○ Implicit relative import는 반드시 사용되지 말아야하고 Python3에서는 삭제된다.
○ Class를 포함하고 있는 모듈에서 Class가 import되었을때, 아래처럼 쓰여지는게 가능하다.
from myclass import MyClass
from foo.bar.yourclass import YourClass
○ 만약에 이런 작성이 로컬 네임과 충돌한다면 그럴경우 아래와 같이 작성되는 것이 좋다.
import myclass
import foo.bar.yourclass
# 그리고 “myclass.MyClas”와 "foo.bar.yourclass.YourClass"를 사용할 것.
Wildcard import
○ Wildcard import(from <module> import *)는 네임스페이스에 존재하는 이름(변수, 함수, 클래스 등)이 명확하지 않고 코드를 읽는 사람과 자동화된 툴에게 혼동을 일으키므로 사용하지 않도록 한다.
○ Wildcard import에 대해 사용이 용인될만한 예가있는데 그것은 public API의 일부로서 internal interface가 다시 개시된 경우이다.
▷ 예를들어 선택적 엑셀러레이터 모듈으로부터의 정의를 통해 인터페이스의 순수한 파이썬의 구현을 덮어 씌우는 것과 정확히 어떤 정의가 덮어 써진 것이 미리 알려지지 않았을 경우가 있다.
○ 이 방법으로 이름이 다시 작성될때에는 아래의 Public과 internal interface 가이드라인이 적용 가능하다.
Module Level Dunder Names
○ Module level “Dunders”(즉, __가 이름앞뒤로 쓰이는)(예: __all__, __author__, __version__, 기타등등) ,은 반드시 모듈 닥스트링 뒤에 쓰여져야 하고, from __future__ import를 제외하고 import문 전에 쓰여져야 한다.
○ 파이썬에서는 future imports는 반드시 닥스트링을 제외하곤 다른 코드 전에 쓰여지는 것을 요구한다.
예시)
"""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
String Quotes(스트링 따옴표)
○ 파이썬에서 따옴표 스트링과 쌍따옴표 스트링은 같다.
○ 여기 PEP에서는 이것에 대한 권장사항을 만들지는 않음, 단지 규칙을 고수하고 그 규칙에 충실할 것을 당부드린다.
○ 스트링에 따옴표 혹은 쌍따옴표를 포함하고 있을때, 스트링에 백슬래시를 피하기 위해 다른 하나를 사용하도록 한다.
○ 3개의 (쌍)따옴표에 대해서는, 닥스트링 규칙(PEP 257)과 일관성을 유지하기 위해 항상 쌍따옴표를 사용하도록 한다.
표현식과 구문에서의 공백
Pet Peeves(눈엣가시)
○ 아래 같은 상황에서 관계없는 공백은 피하도록 한다.
▷ 중괄호, 대괄호, 괄호 안.
좋은 예 :
spam(ham[1], {eggs: 2})
나쁜 예 :
spam( ham[ 1 ], { eggs: 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)
나쁜 예 :
spam (1)
○ 인덱싱 혹은 슬라이싱의 시작을 알리는 여는 괄호 전에서의 공백.
좋은 예 :
dct['key'] = lst[index]
나쁜 예 :
dct ['key'] = lst [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
hypot2 = x * x + y * y
c = (a + b) * (a - b)
○ 키워드 독립변수(keyword argument) 혹은 기본 파라미터 값을 나타내기 위해 “=” 사인 주변에 스페이스를 사용하지 말도록 한다.
좋은 예 :
def complex(real, imag=0.0):
return magic(r=real, i=imag)
나쁜 예 :
def complex(real, imag = 0.0):
return magic(r = real, i = imag)
○ 함수 주석은 콜론에 대해 일반적인 규칙을 사용해야하며, 항상 화살표 주변에 스페이스를 가져야 한다.
좋은 예 :
def munge(input: AnyStr): ...
def munge() -> AnyStr: ...
나쁜 예 :
def munge(input:AnyStr): ...
def munge()->PosInt: ...
○ 함수의 기본값에서의 독립변수 주석을 합칠 때, = 사인 앞뒤로 스페이스를 사용하도록 한다.
(그러나, 오직 그가 주석과 기본값 둘 다 가질 경우만 해당된다.)
좋은 예 :
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): ...
○ 합성구문(Compound statements)(multiple statements on the same line)은 일반적으로 좋지 않다.
좋은 예 :
if foo == 'blah':
do_blah_thing()
do_one()
do_two()
do_three()
나쁜 예 :
if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()
○ 종종 if/for/while구문에서 같은 줄에 짧은 바디가 같이 놓이는 것은 괜찮지만, 여러 줄을 이런식으로 구성하는 것은 하지 않을 것을 당부함. 또한 위의 긴줄을 접는 것은 피하도록 한다.
나쁜 예 :
if foo == 'blah': do_blah_thing()
for x in lst: total += x
while t < 10: t = delay()
매우 나쁜 예 :
if foo == 'blah': do_blah_thing()
else: do_non_blah_thing()
try: something()
finally: cleanup()
do_one(); do_two(); do_three(long, argument,
list, like, this)
if foo == 'blah': one(); two(); three()
뒤에 오는 콤마(Trailing comma)를 사용할 경우
○ 기본적으로 뒤에오는 콤마는 사용자의 선택이다.
▷ 하나의 튜플을 하나의 요소로 만들 때처럼 Trailing comma가 의무적으로 사용되어야 하는 상황은 제외된다.
▷ 파이썬 2에서는 print구문에서 의미를 가질 경우도 포함된다.
○ 명확성을 위해, 의미없는 괄호로 문자를 덮는 것이 권장된다.
좋은 예 :
FILES = ('setup.cfg',)
사용해도 좋지만 헷갈리는 예 :
FILES = 'setup.cfg',
○ 뒤에오는 콤마가 의미없는 상황에서, 콤마는 버전 컨트롤 시스템이 사용될 때 혹은 값의 리스트, 독립변수 혹은 imported된 item들이 확장될 것으로 예상될 때 상당히 도움된다.
○ 패턴은 각각의 값을 그 라인 위에 놓아야하며, 항상 Trailing comma를 추가하여야 하고, 다음 줄에 닫는 괄호를 놓아야 한다.
○ 뒤에 오는 콤마가 닫는 괄호처럼 같은 라인에 있어도 된다는 의미는 아니다.
(하나의 요소를 갖는 튜플은 제외된다.)
좋은 예 :
FILES = [
'setup.cfg',
'tox.ini',
]
initialize(FILES,
error=True,
)
나쁜 예 :
FILES = ['setup.cfg', 'tox.ini',]
initialize(FILES, error=True,)
주석(Comment)
○ 코드와 반대되는 주석은 주석이 없는 것 보다 더 좋지 않다.
○ 항상 코드가 바뀌고 업데이트 될때 주석을 적는데 우선순위를 만들 것을 당부한다.
○ 주석은 완전한 문장이어야 하며, 첫번째 글자는 소문자 식별자로 시작되지 않는 한 대문자로 적도록 한다.
○ 마지막 문장을 제외하곤 문장이 끝에 두개의 스페이스를 사용하도록 한다.
○ 영어를 쓸 때에는 “Strunk and White”(영어 글쓰기 책)를 따르도록 한다.
○ 영어권 국가가 아닌 파이썬 개발자들은 당신이 코드가 국가 사람이 아닌 다른 사람이 읽지 않는다고 120% 확신하지 않는 한 당신들의 주석을 영어로 작성하도록 한다.(영어공부의 중요성...)
블럭 주석(Block comments)
○ 블럭 주석은 일반적으로 완전한 문장의 조합인 하나 이상의 단락으로 구성되어 있다.
○ 블럭 주석은 일반적으로 몇몇의(혹은 모든) 코드에 적용되며, 코드로서 같은 레벨로 들여쓰기가 되어진다.
○ 각각의 블록코맨트 줄은 #와 하나의 스페이스로 시작한다.
(주석 안에서 들여쓰기가 경우가 아닌 경우)
○ 블럭 코멘트 안쪽의 단락은 #를 포함함으로써 분리되어진다.
인라인주석(Inline Comments)
○ 인라인주석은 적당히 사용하도록 한다.
○ 인라인주석은 구문처럼 같은 라인에 있는 주석이다.
○ 인라인주석은 구문으로부터 최소 2개의 스페이스로 구분되어야한다.
▷ 이것들은 #과 하나의 스페이스로 시작된다.
○ 인라인주석은 필요하지 않으며 사실 명확하지 않으면 심란하게 만든다.
▷ 아래와 같이 하지 말것을 당부한다.
x = x + 1 # Increment x
▷ 그러나 아래와 같은경우는 종종 유용하다.
x = x + 1 # Compensate for border
닥스트링(Documentation Strings, Docstrings)
○ 좋은 닥스트링(Documentation Strings)을 작성하는 규정은 PEP257을 참고하도록 한다.
○ 모든 public 모듈, 함수, 클래스, 메소드에 대해 닥스트링을 작성한다.
○ Non-public 메서드에 대해서는 닥스트링이 필요하지 않지만, 메서드가 어떤 역할인지 설명하는 주석을 적어야 하고, 이 주석은 def 라인 다음에 위치해야 한다.
○ PEP 257에서 좋은 닥스트링 작성 규정에 대해 설명하고 있다.
○ 가장 중요한 것은 여러줄로 구성된 닥스트링을 끝내는 “””는 혼자 있어야 함을 명심하도록 한다.
▷ 만약 한줄로 닥스트링이 작성된다면 닫는“””을 같은 줄에 놓아라.
"""Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
네이밍 작성 규칙
○ 파이썬 라이브러리의 네이밍 작성 규칙은 다소 엉망이기 때문에, 완벽한 일관성은 힘들다.
○ 그럼에도 불구하고, 여기 권장되는 네이밍 스탠다드가 있다.
○ 새로운 모듈과 패키지 (서드파티 프레임워크를 포함하여)에서는 이 스탠다드에 맞춰 작성되어야 한다.
○ 그러나 현재 다른스타일을 가지고있는 라이브러리가 존재하는 곳에서는 내부적으로 일관성 있게 하는 것이 선호된다.
가장 중요한 원칙
○ API의 Public 파트로써 유저에게 보여지는 이름은 작성규칙을 실행(implementation)이 아닌 사용법을 반영하는 작성규칙을 따라야 한다.
표현(Descriptive): 네이밍 스타일
○ 서로 다른 여러 네이밍 스타일이 존재하며, 어떤 스타일을 사용할 것인지 결정하는 것을 돕도록 한다.
○ 아래의 네이밍 스타일은 일반적으로 널리 쓰이는 스타일이다.
▷ b (single lowercase letter)
▷ B (single uppercase letter)
▷ lowercase
▷ lower_case_with_underscores
▷ UPPERCASE
▷ UPPER_CASE_WITH_UNDERSCORES
▷ CapitalizedWords (CapWords, CamelCase, StudlyCaps으로 알려져있기도 하다.)
※ CapWord에서 줄임말을 사용할 때, 줄임말의 글자는 모두 대문자로 사용한다.
예를들어 HttpServerError보다는 HTTPServerError이 더 낫다.
▷ mixedCase (첫문자가 소문이기 때문에 CapitalizedWords 와는 다르다.)
▷ Capitalized_Words_With_Underscores (못생겼다..)
○ 이외 고유한 짧은 접두사를 사용하여 그룹을 나타내는 스타일이 존재한다.
▷ 이것은 파이썬에서는 많이 사용되지 않으나, 문서의 완성도를 위해 언급된다.
▷ 예를들어, os.stat() 기능은 st_mode, st_size, st_mtime와 같이 전통적인 이름을 가진 튜플을 반환한다. (이것은 POSIX 시스템 호출 구조체의 필드와의 통신을 강조하기 위해 수행되며, 이 구조체는 프로그래머에게 익숙하다.)
○ X11 라이브러리는 모든 이것의 public 함수에 대해 앞에 X를 사용한다.
※ 파이썬에서 오브젝트가 속성과 메서드 이름에 접두어로 붙고, 함수 이름에 모듈 이름이 접두어로 붙기 때문에 이 스타일은 일반적으로 필요하지 않다고 여겨진다.
○ 추가적으로 앞 혹은 뒤에 _언더스코어를 사용한 아래의 특수 형태가 된다.
(일반적으로 어느 작성규칙에도 조합 가능하다.)
▷ _single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
▷ single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g.
▷ Tkinter.Toplevel(master, class_='ClassName')
▷ __double_leading_underscore: when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes_FooBar__boo; see below).
▷ __double_leading_and_trailing_underscore__: "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.
규정(Prescriptive): 네이밍 규칙
피해야할 이름
○ I(소문자, 엘), O(대문자, 오), 혹은 I(대문자, 아이)는 한글자 변수이름으로써 사용하지 말도록 한다.
▷ 몇몇의 폰트에서는, 이 글자들은 숫자 1 혹은 0과 구분이 쉽지 않으므로 l(소문자, 엘)을 사용할 때 L을 대신해서 사용하도록 한다.
ASCII 호환성
○ ASCII PEP3131의 Policy section에서 설명되있는 것과 같이 표준 라이브러리에서 사용된 식별자는 ASCII와 호환이 가능하여야 한다.
패키지와 모듈 이름
○ 모듈은 짧으며 모두 소문자인 이름을 가져야 한다.
○ 언더스코어는 가독성을 향상시킬 수 있을 경우에 모듈의 이름에 사용될 수 있다.
○ 파이썬 패키지의 이름 또한 짧으며 모두 소문자여야 하지만, 언더코어는 사용될 수 없다.
○ C혹은 C++로 씌여진 확장 모듈이 높은 레벨(더욱 객채향적인) 인터페이스를 제공하는 파이썬 모듈을 가질때, C/C++ 모듈은 이름 앞에 언더스코어가 있어야 한다.
클래스 이름
○ 클래스의 이름은 CapWords 작성규칙을 사용한다.
○ 함수에 대한 이름 작성 규칙은 인터페이스가 문서화되고 주로 호출이 가능하게 사용되어질 경우 대신에 사용된다.
○ 내장 이름에 대한 별도의 작성규칙이 있다.
▷ 대부분의 내장 이름은 하나의 단어(혹은 두 단어가 함께 실행됨)이다.
▷ 보통 예외이름(Exception name)과 내장 상수에 사용되는 CapWords 작성규칙이 사용된다.
타입 변수 이름
○ PEP484에 소개된 타입 변수의 이름은 짧은 이름을 선호하는 CapWord방식을 사용한다.
○ T, AnyStr, Num과 같이 공변(covariant)하거나 반변(contravariant)하는 거동을 선언하기 위해 사용되는 변수들에 대해서는 접미사 _co 혹은 _contra가 붙여지는 것이 권장된다.
from typing import TypeVar
VT_co = TypeVar('VT_co', covariant=True)
KT_contra = TypeVar('KT_contra', contravariant=True)
예외이름(Exception Names)
○ 예외는 클래스어야 하기 때문에 클래스 이름 작성규칙은 여기에도 적용한다.
○ 그러나 Error접미사를 예외 이름에 사용되게 된다. (예외가 에러일 경우)
전역 변수 이름
○ 이 변수들은 하나의 모듈 안에서만 사용되기가 권장된다.
○ 작성규칙은 함수에 대한 작성 규칙과 거의 비슷하다.
○ from M import *를 이용하여 사용되게 설계된 모듈은 전역변수들을 exporting하기 위해 __all__ 매커니즘을 사용하여야 하며 혹은 언더스코어를 위의 전역변수 앞에 접두사로 붙이는 구식의 작성규칙을 사용하여야 한다.
함수 및 변수 이름
○ 함수이름은 가독성을 개선시켜야하므로, 언더스코어로 구분된 소문자 단어로 구성된다.
○ 변수이름은 함수이름과 같은 작성규칙을 따른다.
○ mixedCase는 오로지 이전버전의 호환성을 유지할 필요가 있을 경우만 허락된다.
함수와 메서드의 독립변수
○ 항상 인스턴트 메서드에 대한 첫번째 독립변수에는 self를 사용한다.
○ 항상 클래스 매서드에 대한 첫번째 독립변수에는 cls를 사용한다.
○ 만약 함수 독립변수의 이름이 사용된 키워드와 충돌한다면, 축약형 혹은 철자를 바꾸는 것보다 하나의 언더스코어를 끝에 덧붙이는 것이 일반적으로 더 좋게 만든다.
▷ class_가 clss보다 낫다. (더 나은 것은 동의어를 사용하여 충돌을 피하는 것이다.)
메서드 이름 그리고 인스턴스 변수
○ 함수 네이밍 규칙을 사용하도록 한다.
▷ 가독성 개선을 위해 언더스코어로 구분된 소문자 단어들을 사용한다.
○ Non-public 메서드와 인스턴스 변수에 대해서만 앞에 언더스코어를 사용한다.
○ 서브클래스를 사용할 때 이름 충돌을 피하기 위해, 파이썬의 맹글링 규칙에 따라 변수 앞에 2개의 언더스코어를 사용한다.
○ 파이썬은 클래스 이름과 함께 그 이름들을 심하게 훼손한다.
▷ 만약 클래스 Foo가 __a로 명명된 속성을 가진다면 이것은 Foo.__a로 접근할 수 없다.
(고집스런 유저라면 Foo._Foo__a을 호출함으로써 접근할 수 있다.)
○ 일반적으로 변수앞 두개의 언더스코어는 서브클래스로 설계된 클레스에서 속성에 대해 이름 충돌을 피하기 위해 사용된다.
※ 참고사항: __ 이름에 대한 논란은 아직도 존재한다.
상수(constants)
○ 상수는 모듈레벨에서 정의되고, 언더스코어로 구분되어 대문자로 작성된다.
▷ 예제: MAX_OVERFLOW , TOTAL
상속을 위한 설계
○ 항상 클레스의 메서드와 인스턴스 변수가 public이되는지 non-public이 되는지 결정하도록 한다.
▷ 만약 확신하지 못한다면 non-public 으로 결정하는 것이 좋다. (public을 non-public으로 만드는 것보다 non-public을 public 속성으로 만드는 것이 더 쉽다.)
○ Public속성은 사용을 위한 클래스의 관련없는 클라이언트라고 예상되는 것이며, 호환되지 않는 변경사항을 피하도록 노력한다.
○ Non-public 속성은 서드파티에 의해 사용되지 않는 것이다.
▷ Non-public 속성은 바뀌지 않거나 제거되지 않는다는 것이 보장되지 않는다.
○ 파이썬에서는 “private” 속성이 없기 때문에, “private”라는 용어를 여기서는 사용하지 않는다.
○ 속성의 또 다른 카테고리는 서브클래스 API의 부분이다. (종종 “protected”라고 다른 언어에서 불림)
▷ 몇몇의 클래스는 클래스 기능의 수정과 확장을 위해 상속을 염두해 두고 설계된다. 위의 클래스를 설계할 때, 속성이 public이고, 서브클라스 API의 일부이고 기초클래스에 의해 사용되는 것에 관한 explicit 결정(decisions)을 만들 수 있음에 주의하도록 한다.
○ 위와 관련하여 파이썬 다운 가이드라인이 아래에 제시된다.
▷ Public 속성은 이름앞에 _언더스코어를 가지지 않는다.
▷ 만약 public 속성 이름이 예약된 키워드와 충돌한다면, 이름 뒤에 하나의 언더스코어(_)를 붙이도록 한다. 이것은 축약형이나 스펠링을 파괴하는 것보다 선호되는 방법이다.
(그러나, 여기 ‘cls’는 어떤 클래스로 잘 알려진 변수 혹은 독립변수에 대해(특히 클래스 메서드에서 첫번째 독립변수) 선호되는 스팰링이다.)
※ 참고 1: 위의 클래스 매서드에 대한 독립변수 이름 권장사항을 참고하도록 한다.
○ 단순한 public 데이터 속성에 대해, 복잡한 접근자/유발자(mutator) 방법없이 속성 이름을 노출하는 것이 최고의 방법이다. 만약 당신이 단순한 데이터 속성이 기능적으로 향상되는 것을 필요로 할때, 파이썬은 미래의 향상에 대한 쉬운 경로를 제공함을 명심하도록 하라.
※ 참고 1: 특성,속성(Properties)는 세로운 스타일의 클래스에서만 작동한다.
※ 참고 2: Cahing과 같은 부작용은 일반적으로 괜찮지만 부작용이 없는 기능적인 일을 유지하도록 시도하도록 한다.
※ 참고 3: 계산적으로 상당한 작동을 요구하는 특성(Properties)을 사용하는 것을 피하도록 한다.
속성(attribute) 표기법은 호출자가 상대적으로 적은 비용으로 접근할 수 있게한다.
○ 만약 클래스가 서브클래스화 되는 것이 고려될 때, 서브클래스에서 사용하길 원하지 않는 속성을 가지고 있다면, 이름 앞에 두개의 언더스코어를 활용하는 네이밍과 이름 끝에는 언더스코어를 작성하지 않는 것을 고려하도록 한다.
※ 참고 1: 단순한 클래스명은 맹글링된 이름에서 사용된다는 것을 참고하도록 한다.
만약에 서브클래스가 같은 클래스 이름과 같은 속성을 이름을 선택한다면, 여전히 이름 충돌을 가질 수 있다.
※ 참고 2: 이름 맹글링은 덜 편리한 디버깅과 __getattr__()과 같이 확실한 사용을 만들 수 있으나 이름 맹글링 알고리즘은 잘 서류화(documentated)되며 수행하기 쉽다.
※ 참고 3: 모두가 이름 맹글링을 좋아할 수는 없다. 향상된 호출자에 의한 잠재적 사용을 활용하여 이름 충돌을 피하기 위한 요구에 밸런스를 맞추는 것을 시도하도록 한다.
Public과 내부 인터페이스
○ 이전버전과의 호환성 보장은 오직 public 인터페이스에게만 적용한다.
▷ 그런이유로, 유저들이 명확히 public과 내부 인터페이스 간을 구분할 수 있게 하는건 매우 중요하다.
○ 이전 버전과의 호환성 보장을 하지 않는한 문서(Documentation)가 그들을 임시적 혹은 내부의 인터페이스라고 선언하지 않는한 문서화된(Documented) 인터페이스는 public을 고려한다.
▷ 모든 기록화(Documentated)되지 않은 인터페이스들은 내부에 있다고 가정된다.
○ 검토를 더 낫게 하기 위해, 모듈은 이름을 public API 내부에서 __all__ 속성을 사용하여 선언해야한다.
▷ 빈 리스트에서의 __all__ 세팅은 모듈이 public API를 가지고 있지 않음을 나타낸다.
○ __all__을 적당하게 사용하여, 내부 인터페이스(패키지, 모듈, 클래스, 함수, 속성 혹은 다른 이름들)은 하나의 언더스코어를 사용하여 접두어를 붙여야 한다.
○ 만약 어느 네임스페이스(패키지 모듈 혹은 클래스)가 내부로 고려된다면, 어느 인터페이스도 내부로 고려된다.
○ Import된 이름들은 항상 세부구분사항으로 고려되어야 한다.
▷ 다른 모듈은, 그들이 서브모듈로부터 기능을 보여주는 os.path 혹은 패키지의 __init__ 모듈과 같이 명시적으로 보유하고있는 모듈의 API를 문서화(Documentated)된 부분이 아니라면, 반드시 import된 이름에 대한 간접적인 접근에 의지해서는 안된다.
프로그래밍 권장사항
○ 파이썬의 다른 인터프리터(PyPy, Jython, IronPython, Cython, Psyco, 등..)에 불리하지 않은 방법으로 코드가 작성되어야 한다.
▷ 예를 들어, a+=b 또는 a=a+b 형식의 명령문에 대한 CPython의 내부 문자열 연결의 효율적인 구현에 의존해선 안됨. 이 최적화는 CPython에서도 취약하며(일부 유형에서만 작동 한다.) refcounting을 사용하지 않는 구현에서는 전혀 존재하지 않는다.
▷ 라이브러리의 성능에 민감한부분에 대해선 ‘’.join() 형태를 대신에 사용하여야 한다. 이는 다양한 실행에 걸처 선형시간에서 연속이 일어나게 한다.
○ None과 같이 개체에 대한 비교는 equality operator가 아니라 반드시 is 혹은 is not과 함께 수행되야 한다.
▷ “if x is not None”을 사용할 때(None이 디폴트로 되어있는 변수 혹은 독립변수를 다른 값으로 세팅이 되는지 아닌지 테스트할 때) “if x”를 작성하는 것에 주의하도록 한다. (다른 값은 불린 context에서 false이 될 수 있는 타입을 가진다.)
▷ Not … is 보다는 Is not 오퍼레이터를 사용할 것. 두 표현식은 기능적으로 같으나, is not이 더욱 가독성이 좋다.
좋은 예 :
if foo is not None:
나쁜 예 :
if not foo is None:
○ 다양한 비교를 사용하여 순서 지정 연산을 구현할 때에는, 특정 코드만 사용하여 다른 코드를 사용하는 대신 6가지 연산 (__eq__, __ne__, __ lt__, __le__, __gt__, __ge__)을 모두 구현하는 것이 가장 좋다.
▷ 위와 관련되어 투입되는 시간과 노력을 최소하기 위해, functools.total_ordering() 데코레이터는 누락된 비교 메소드를 생성하는 도구를 제공한다.
▷ PEP 207은 reflexivity 규칙이 파이썬에 의해 가정됨을 나타냄. 따라서, 인터프리터는 y> x와 x <y, y> = x를 x <= y로 바꾸고 x == y 및 x! = y의 인수를 서로 바꿀 수 있다.
▷ sort () 및 min () 연산은 <연산자를 사용하도록 보장되며 max () 함수는> 연산자를 사용하나 그러나 다른 상황에서 혼동이 발생하지 않도록 6가지 작업을 모두 구현하는 것이 가장 좋다.
○ 람다 표현식을 식별자에 직접 바인드하는 할당문 대신에 항상 def 문을 사용하도록 한다.
좋은 예 :
def f(x): return 2*x
나쁜 예 :
f = lambda x: 2*x
▷ 첫번째 형태는 결과함수 오브젝트의 이름이 ‘<lambda>’가 아니라 ‘f’ 인 것을 의미한다.
▷ 일반적으로 트레이스백과 문자열(string) 표현에 대해서는 이것이 더 유용하다.
▷ 할당문의 사용은 람다표현식이 제공하는 def구문보다 더 유리한 장점을 제거한다.
(즉 더 큰 표현식에 포함될 수 있다.)
○ BaseException보단 Exception으로부터 예외를 얻도록 한다.
▷ BaseExcepction으로부터의 직접적인 상속은 예외를 잡는 것이 거의 항상 잘못되는 경우를 위해 남아있다.
▷ 예외가 발생하는 위치가 아니라 예외를 잡는 코드가 필요할 수 있는 구분을 기반으로 예외 체계를 설계하도록 한다.
▷ “문제가 발생했다” 라고 시작하는 것보다는 “무엇이 문제로 이끄는가”에 대한 질문에 대답하는 것을 목표로 하도록 한다.
(내장예외계층에 대해 설명하는 PEP 3151을 참고하라.)
▷ 예외가 에러인 상황에서 당신의 예외클래스에 “Error” 접미사를 더하더라도, 클래스 네이밍 작성규칙은 여기를 적용하도록 한다.
▷ 비로컬 흐름 제어 또는 다른 형태의 시그널링에 사용되는 에러가 없는 예외는 접두사를 붙일 필요는 없다.
○ 예외 체인을 적절히 사용하도록 한다.
▷ 파이썬 3에서, “raise X from Y”는 오리지날 트레이싱을 잃어버리지 않고 explicit replacement를 나타낼 때 사용된다.
▷ 의도적으로 내부 예외(파이썬2에서는 “raise X” 사용하거나 파이썬 3.3+에서는 “raise X from None”를 사용하여)가 교체될 때, 관련 세부 사항이 새로운 예외(예: KeyError를 AttributeError로 변환 할 때 속성 이름을 유지하거나 원래 예외의 텍스트를 새로운 예외 메시지에 포함하는 경우)로 전송되는지 확인하도록 한다.
○ 파이썬 2에서 예외가 나타날때, “raise ValueError, 'message'”와 같이 오래된 형태보다는 “raise ValueError(‘message’)를 사용하도록 한다.
▷ 전자의 경위 Python3에서는 문법적으로 맞지 않다.
▷ paren-using형식은 에외 독립변수가 길거나 문자열 포맷을 포함하고 있을때 포함된 괄호덕에 연속문자를 사용할 필요가 없다는 것을 의미한다.
○ 예외를 선정할 때, 가능하다면 except:를 사용하는 것 보단 특정한 예외를 언급하도록 한다.
try:
import platform_specific_module
except ImportError:
platform_specific_module = None
○ bare except:절은 컨트롤C를 사용하여 프로그램을 중단시키는 것을 어렵게 만드는 SystemExit와 KeyboardInterrupt 예외를 잡을 수 있고, 다른 문제를 숨길 수 있다.
▷ 만약 사용자가 모든 예외를 잡길 원한다면 except Exception:를 사용하도록 한다.
(bare except는 except BaseException:과 동일하다.)
▷ 가장 좋은 규칙은 아래의 두 케이스에서 bare ‘except’ 구문의 사용을 제한하도록 한다.
1. 만약 예외 핸들러가 트랙백을 출력하거나 로그를 만든다면, 최소 사용자는 에러가 났다는 것을 알 것이다.
2. 만약 코드가 정리작업 필요하다면, 그러나 그때에 예외가 raise를 사용해서 다음에 전파하지 못하게 만든다.
try...finally가 이런 케이스를 다루기 위해서는 더 나은 방법이다.
○ 이름에 대해 발견된 예외를 바인딩할때, 파이썬 2.6에서 추가된 explicit 이름 바인딩 문법을 선호하도록 한다.
try:
process_data()
except Exception as exc:
raise DataProcessingFailedError(str(exc))
▷ 이것은 파이썬 3에서만 지원되는 구문이고, 오래된 콤마 기반 구문과 연관된 애매한 문제들을 피하게 할 수 있다.
○ 작동 시스템 에러를 잡을때, errno 값의 인트로 스팩션을 통해 파이썬 3.3에서는 explicit 예외 계층을 선호하도록 한다.
○ 모든 try/except 구문에 대해, try 구문의 절대적인 수를 최소한으로 제한하도록 한다.
▷ 다시 설명하면, 이것은 버그를 감출수 없게 한다.
좋은 예 :
try:
value = collection[key]
except KeyError:
return key_not_found(key)
else:
return handle_value(value)
나쁜 예 :
try:
# Too broad!
return handle_value(collection[key])
except KeyError:
# Will also catch KeyError raised by handle_value()
return key_not_found(key)
○ 리소스가 코드의 특정한 섹션에 위치할때, 이것이 사용 이후에 즉시 그리고 신뢰성있게 정리되는 것을 보장하도록 “with”구문을 사용하도록 하거나, 혹은 try/finally 구문 역시 적용할만하다.
○ 리소스를 얻거나 제공할때를 제외하고는 어떤 것을 할때든 별도의 함수 혹은 메서드를 통해 콘텍스트 매니저는 호출되어야 한다.
좋은 예 :
with conn.begin_transaction():
do_stuff_in_transaction(conn)
나쁜 예 :
with conn:
do_stuff_in_transaction(conn)
○ return 구문에서 일관성을 유지하도록 한다.
▷ 함수에 있는 모든 return 구문은 반드시 표현식을 반환하거나, 없어야한다.
▷ 만약 어떤 return 구문이 표현식을 반환했다면, 어떤 return 구문이 반환되는 값이 없는 곳에서는 “return None”을 명시하고, 함수의 끝에 (만약 도달할 수 있다면) explitict return 구문이 존재해야한다.
좋은 예 :
def foo(x):
if x >= 0:
return math.sqrt(x)
else:
return None
def bar(x):
if x < 0:
return None
return math.sqrt(x)
나쁜 예 :
def foo(x):
if x >= 0:
return math.sqrt(x)
def bar(x):
if x < 0:
return
return math.sqrt(x)
○ 문자열 모듈 대신에 문자열 메서드를 사용하도록 한다.
▷ 문자열 메서드는 항상 빠르고, 유니코드 문자열을 사용하여 같은 API를 공유한다.
▷ 만약 파이썬 2.0보다 더 오래된 이전 버전과의 호환성이 요구된다면 이 역할을 무시하도록 한다.
○ 접두사 혹은 접미사를 확인하기 위해서는 문자열 슬라이싱 대신에 ''.startswith()과 ''.endswith()를 사용하도록 한다.
▷ startswith()과 endswith()는 더 명확하며 에러가 덜 발생하기 쉽다.
좋은 예 :
if foo.startswith('bar'):
나쁜 예 :
if foo[:3] == 'bar':
○ 오브젝트 타입 비교는 항상 직접적으로 타입을 비교하는 것 대신 isinstance()를 사용하여야 한다.
좋은 예 :
if isinstance(obj, int):
나쁜 예 :
if type(obj) is type(1):
○ 오브젝트가 문자열인지 아닌지 확인할 때에는, 이것이 유니코드 문자열이어야 한다는 것을 명심하도록 하라.
▷ 파이썬 2에서는 str과 유니코드는 공통 베이스 클래스(basestring)를 가진다.
if isinstance(obj, basestring):
▷ 파이썬 3에서는 Unicode, basestring 더이상 존재하지 않으며(오직 str만 존재한다.), 바이트개체는 더이상 문자열의 종류가 아니다. (대신 정수 시퀀스이다.)
○ 시퀀스(문자열, 리스트, 튜플)에 대해, 비어있는 시퀀스는 false라는 것을 사용하도록 한다.
좋은 예 :
if not seq:
if seq:
나쁜 예 :
if len(seq):
if not len(seq):
○ 상당한 후행공백에 의존하는 문자열을 리터럴을 작성하지 말도록 한다.
▷ 후행공백은 시각적으로 구분되지 않고 몇몇의 에디터들(혹은 최근에는 reindent.py)에게 후에 제거될 수도 있다.
▷ 불린 값을 True 혹은 false에 ==을 사용하여 비교하지 말도록 한다.
좋은 예 :
if greeting:
나쁜 예 :
if greeting == True:
더 나쁜 예 :
if greeting is True:
함수 주석
○ PEP484를 수용하면, 함수 주석에 대한 스타일 규칙은 바뀐다.
○ 이후 버전과의 호환성을 위해, 파이썬 3에서 함수주석은 PEP 484 문법을 사용하는 것이 권장된다.
(이전 섹션에 주석에 대한 포맷 권장사항이 있으므로 이를 참고하라.)
○ 이전에 이 PEP에서 추천되었던 주석스타일에 대한 실험은 더 이상 권장되지 않는다.
○ 그러나 stdlib의 밖에서는, PEP484의 규칙 내에서의 실험은 현재 권장된다.
▷ 예를들어 PEP 484스타일 주석을 사용하는 서드파티 라이브러리나 어플리케이션을 마크업하는 것과, 쉽게 주석을 리뷰하는 것, 그들의 존재 여부를 관찰하는 것은 코드에 대한 이해도를 개선시킨다.
○ 파이썬 표준라이브러리는 위의 주석을 시도하는 것에 보수적이다.
▷ 그러나 그것들의 사용은 새로운 코드 그리고 대형 재작성(refactoring)에서 허락하도록 한다.
○ 다른 형태의 함수주석을 만들기를 원하는 코드에 대해선 아래와 같은 형태의 주석을 달아 놓는 것이 권장된다.
# type: ignore
▷ 파일의 가장 위 부근에서, 이것은 Type checker에게 모든 주석이 무시됨을 의미한다.
(Type checker로부터의 불만을 제거할 좋은 방법은 PEP 484에서 찾을 수 있다.)
○ Type checker는 선택사항이며 별도의 툴이다.
▷ 기본 파이썬 인터프리터는 타입 확인에 의한 어떤 메세지도 발행하지 않으며 주석에 기반한 그들의 행동을 고쳐서는 안된다.
▷ Type checker를 사용하는 것을 원하지 않는 사용자가 Type checker를 무시하는 것에 대해서는 자유이다.
▷ 그러나 서드파티 라이브러리 패키지의 사용자들이 그들의 패키지를 사용하여 Type checker를 작동시키는 것이 예상되며, 이런 목적에 대해 PEP484는 stub 파일의 사용을 추천한다.
▷ Type checker가 해당 py파일을 사용하여 읽을 수 있는 Pyi 파일,Stub 파일은 라이브러리 혹은 별도의 (라이브러리 작성자의 허가가 있을 때) typeshed repo(유형이 지정된 저장소)를 통해 구분되어질 수 있다.
○ 이전버전과의 호환성이 필요한 코드에 대해서는, 주석(comment) 형태의 타입 주석(annotation)이 추가될 수 있고, PEP 484의 관련된 섹션을 참고하라.
변수 주석
○ PEP 526는 변수주석을 소개하는 문서임. 변수에 대한 스타일 권장사항은 위에 설명된 함수주석과 유사하다.
○ 모듈 레벨 변수, 클래스와 인스턴스 변수, 지역변수에 대한 주석은 콜론 이후 하나의 스페이스를 가진다.
○ 콜론 전에는 스페이스가 없다.
○ 배정이 오른쪽이라면, 그때에는 이퀄리티 사인은 양쪽에 하나의 스페이스를 가져야 한다.
좋은 예 :
code: int
class Point:
coords: Tuple[int, int]
label: str = '<unknown>'
나쁜 예 :
code:int # No space after colon
code : int # Space before colon
class Test:
result: int=0 # No spaces around equality sign
○ PEP 526이 파이썬 3.6에 허가됬음에도 불구하고, 변수주석문법은 파이썬의 모든 버전의 stub 파일에서 선호되는 문법이다.(PEP 484 참고하라.)
'Python > 파이썬 기초' 카테고리의 다른 글
문자열형(string)과 관련 함수/메서드 - 파이썬 기초(5) (0) | 2018.11.12 |
---|---|
시퀀스형(리스트, 튜플, 레인지)과 관련 함수/메서드 - 파이썬 기초(4) (0) | 2018.11.11 |
숫자형(정수형,실수형,복소수형)과 산술 연산자/메서드 - 파이썬 기초(3) (0) | 2018.11.10 |
논리형(boolean), 논리 연산자, 비교 연산자 - 파이썬 기초(2) (0) | 2018.11.08 |
파이썬의 개요, 특징, 활용 가능성 - 파이썬 기초(1) (0) | 2018.11.04 |
댓글