질문이 있으십니까?

기본 컨텐츠 및 사용자가 직접 참여하여 만들어진 다양한 내용을 검색합니다.

Python 개발자 1명이 개발한 것 처럼

들여쓰기

4개의 공백을 들여쓰기의 단위로 사용하라.

hanging indent

문장 중간에 들여쓰기를 사용하는 형식

좋은 예

# 구분자를 사용하여 정렬하기
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)
#여러 줄에 걸친 괄호/중괄호/대괄호를 닫을 경우 리스트의 마지막 항목에 맞추어 다음 줄에 닫는 표시를 할 수 있다
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,
]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
)

나쁜 예

# 수직 정렬을 하지 않는다면, 인수를 첫 번째 줄에 사용하지 마라.
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)

탭이냐? 공백이냐?

  • 절대 탭 문자와 공백 문자를 섞어 쓰지 마라.
  • 파이썬에서 들여쓰기에 주로 사용되는 방식은 공백 문자만 사용하는 것이다.
  • 두 번째로 많이 쓰이는 방식은 탭 문자만 사용하는 것이다.
  • 섞여 쓸 경우 탭 문 자와 공백 문자가 섞인 코드는 반드시 공백 문자만 사용한 코드로 변환해 야 한다. -t 옵션을 사용하여 파이썬 명령줄 인터프리터를 호출하면 탭 문자와 공백 문자가 섞인 코드가 있을 경우 인터프리터가 경고 메시지 를 표시한다. -tt 옵션을 사용하면 이 경고 메시지가 에러 메시지로 표시된다. 위 옵션들을 사용하기를 권한다.

한 행의 최대 길이

  • 원칙 한 행에는 최대 79글자까지만 넣도록 한다.
  • 이유1 한 행에 80글자까지만 표시할 수 있는 장비들이 아직 많이 남아 있다
  • 이유2 창 하나에 80글자만 표시하도록 강제할 경우 여러 창을 열어서 늘어놓고 작업할 수 있다.
  • 이유3 80글자 제한이 있는 장치에서 자동 줄 바꿈(wrapping)이 일어날 경우 코드의 시각적인 구조가 망가지며, 이렇게 되면 코드를 이해하기 어려워진다
글자가 많은 행에 줄바꿈을 적용할 경우 좋은 방법은 괄호, 중괄호, 대괄 호 등의 내부에 여러 행의 코드를 적는 것이다. 파이썬에서 이들 코드는 암시적으로 계속 이어지는 것으로 처리된다. 괄호를 사용한 줄바꿈을 적 용하여 긴 코드를 여러 행의 코드로 바꿀 수 있다. 이 방법은 줄이 계속 됨을 나타내는 백슬래시(‘') 문자를 사용하기 전에 사용해야 한다. 이 진 연산자에서 줄바꿈을 할 경우 줄바꿈하기 좋은 곳은 연산자의 다음 위치이다(이전 위치가 아니다). 몇 가지 예를 살펴보자
class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
            color == 'red' and emphasis == 'strong' or
            highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

빈 줄

  • 최상위 수준 함수와 클래스 정의는 두 줄을 띄워서 구분한다.
  • 클래스의 메서드 정의는 한 줄을 띄워서 구분한다.
  • 서로 연관이 있는 함수들의 묶음을 구분하기 위해 빈 줄을 추가로 사용할 수 있다. 반대로 한 줄짜리 구현 코드가 뭉쳐 있을 경우 이러한 빈 줄을 생략할 수도 있다. (예: 일련의 미구현, 임시 코드)
  • 함수 내에서 논리적인 단위를 드러내기 위해 빈 줄을 사용하라. (하지만 아껴서 사용하자)
  • 파이썬은 컨트롤-L(^L) 폼 피드 문자를 공백으로 취급한다; 많은 프로그 램이 이 문자를 페이지 구분자로 취급하며, 파일 내에서 서로 연관성이 있는 단락을 페이지별로 구분하는데 이 문자를 사용할 수 있다. 특정 편집기나 웹 기반의 코드 뷰어는 컨트롤-L을 폼 피드 문자로 인식하지 않을 수도 있으며, 이 경우 폼 피드를 대신하는 다른 문자가 컨트롤-L 문자의 위치에 표시될 것이다.

임포트

  • 좋음 import os import sys
  • 나쁨 import sys, os
  • 좋음 from subprocess import Popen, PIPE
  • 규칙1 항상 파일의 최상단에 위치하라
  • 규칙2 모듈의 주석문과 docstring의 바로 다음, 그리고 모듈의 전역 변수와 상수 바로 이전에 위치하라.
  • 순서1 표준라이브러리
  • 순서2 관련이 있는 서드파트 라이브러리
  • 순서3 로컬 어플리케이션 / 자체 라이브러리
  • 주의 인접(relative) 경로를 사용하여 내부 패키지를 임포트하지 않도록 한 다. 항상 절대 패키지 경로를 사용하여 임포트를 하도록 하자. 절대 임포트 (역주: 절대 경로를 사용한 임포트)는 이식성이 높으며, 일반적으로 읽기 더 쉽다.
#클래스를 포함하고 있는 모듈에서 클래스를 임포트할 때, 보통은 다음 과 같이 기술
from myclass import MyClass
from foo.bar.yourclass import YourClass

#만약 이름이 이미 선언된 로컬 이름과 충돌할 경우, 다음과 같이 기술
import myclass
import foo.bar.yourclass
#그런 다음 “myclass.MyClass”, “foo.bar.yourclass.YourClass” 같은 식으로 클래스를 사용하면 된다.

공백 문자

#괄호, 중괄호, 대괄호 내부에 연결되는 부분
좋음: spam(ham[1], {eggs: 2})
나쁨: spam( ham[ 1 ], { eggs: 2 } )

#콤마, 세미콜론, 콜론의 이전 위치
좋음: if x == 4: print x, y; x, y = y, x
나쁨: if x == 4 : print x , y ; x , y = y , x

#함수 호출시 인수 목록이 시작되는 괄호의 바로 이전 위치
좋음: spam(1)
나쁨: spam (1)

#인덱싱 혹은 슬라이싱이 시작되는 괄호의 바로 이전 위치
좋음: dict['key'] = list[index]
나쁨: dict ['key'] = list [index]

#할당(혹은 기타 다른) 연산자 주변에 한 개를 초과하는 공백 문자가 있는 경우
좋음
x = 1
y = 2
long_variable = 3

나쁨
x             = 1
y             = 2
long_variable = 3

기타

#우선순위를 부여할 때
#좋음
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)

#키워드 인수 혹은 기본 매개변수 값을 나타내는 경우에는 = 기호 주위에 공백을 넣지 않는다.
#좋음
def complex(real, imag=0.0):
    return magic(r=real, i=imag)
#나쁨
def complex(real, imag = 0.0):
    return magic(r = real, i = imag)

#복합 구문(Compound statements, 여러 구문이 한 줄에 있는 것)은 일반 적으로 권장되지 않는다.
#좋음
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()

주석

블록 주석문

  • 각 행은 #문자와 한 개의 공백으로 시작된다

인라인 주석문

  • # 문자와 한 개의 공백으로 시작해야 한다.
# 뻔한 주석문은 피하자
x = x + 1                 # x의 증가

# 이런 주석이 유용하다.
x = x + 1                 # 경계값에 대한 보상

문서화 문자열

  • 좋은 문서화 문자열(Documentation String, docstring이라고도 한다)을 작성하기 위한 규칙으로 PEP 257가 널리 알려져 있다.
  • public으로 정의된 모든 모듈, 함수, 클래스, 메서드에 대해 docstring 을 작성한다. public으로 정의되지 않은 메서드에는 docstring을 작성 할 필요가 없다. 하지만 해당 메서드가 무슨 일을 하는지 설명하는 주 석은 달아야 한다. 이러한 주석은 def가 있는 행 바로 다음 행에 작성한다.
  • PEP 257은 좋은 docstring 작성 규칙에 대해 기술하고 있다. """ 영역이 끝나는 부분에서는 한 줄 전체에 """ 문자를 넣고, 바로 위 의 한 줄을 빈 줄로 두어야 한다
"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""

기타

# try 절이 적용되는 코드의 범위를 최소화하라. 버그가 겹치는 일을 막아준다.
# 좋음
try:
    value = collection[key]
except KeyError:
    return key_not_found(key)
else:
    return handle_value(value)

#나쁨
try:
    # 코드 적용 범위가 넓다!
    return handle_value(collection[key])
except KeyError:
    # 여기서는 handle_value()이 발생시킨 KeyError 예외를 처리
    return key_not_found(key)

         with conn.begin_transaction():
             do_stuff_in_transaction(conn)
# 문자열의 접두사/접미사를 확인하기 위해 문자열을 직접 자르는 대신
좋음: if foo.startswith('bar'):
나쁨: if foo[:3] == 'bar':

# 객체 타입 비교 시, 타입을 직접 비교하는 대신 항상 isinstance()를 사용
좋음: if isinstance(obj, int):
나쁨: if type(obj) is type(1):
# 배열 형태의 타입(문자열, 리스트, 튜플)은 그 내용이 비어있을 때 false를 반환한다는 사실
좋음: if not seq:
      if seq:

나쁨:if len(seq)
     if not len(seq)

# ==를 사용해서 True/False 값을 부울 값과 비교하지 않는다
좋음:   if greeting:
나쁨:   if greeting == True:
최악:   if greeting is True:

개발자가 아무렇게나 소스코드를 짤 수 있지만, 항시 나의 부사수가 인수인계를 받는 다는 마음과, 팀원이 소스코드를 공유한다는 마음으로 위의 규칙들을 철저히 이행하는 습관을 갖어야 합니다.

댓글을 작성하세요

문서 이력

  • 2020-06-13 날짜로 신달수 님으로 부터 컨텐츠명이 변경 되었습니다.
  • 2020-06-15 날짜로 신달수 님께서 등록 작업을 하였습니다.