본문 바로가기

카테고리 없음

Python Google Style Guide

1. Lint

pylint 를 사용하여 코드 컨벤션을 맞춘다.

 

2. import

 

- import  x 를 통해 패키지와 모듈을 사용한다.

 

- from x import y : x가 package이고, y가 모듈일때 사용한다.

 

- from x import y as z : y로 이름지어진 모듈이 두개거나, y 모듈 이름이 불필요하게 길다면 z로 약어를 만들어 사용한다.

 

- import y as z : z가 공식적인 약어인 경우에만 사용한다. (ex, numpy의 np)

 

- import된 모듈과 관련있는 이름은 사용하지 않는다.

 

- 모듈이 같은 패키지에 있더라도 전체 패키지 이름을 사용한다. 이는 동일한 패키지를 두번 import하는것을 예방한다.

 

3. Packages

 

- 모든 코드는 전체 패키지 이름을 명시하며 import 해야한다.

 

올바른 예

# Reference absl.flags in code with the complete name (verbose).
import absl.flags
from doctor.who import jodie

FLAGS = absl.flags.FLAGS

 

부적절한 예 (이 파일은 doctor/who/ 에 있다고 가정하고 jodie.py또한 존재한다고 가정.)

# Unclear what module the author wanted and what will be imported.  The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie

 

3. 전역변수

 

- 전역변수를 사용하지 말 것

 

- 전역 변수는 기술적으로 변수이지만 module-level 상수가 허용되고 권장된다.

 

- 만약 전역변수가 필요하다면 module-level에서 선언되고 모듈 내부에서 이름에 _를 붙여서 만들어져야 한다. 예를 들어 _MAX_HOLY_HANDGRENADE_COUNT = 3. 상수는 반드시 모든 공백 _를 넣어서 이름을 만들어야 한다. 

 

4. 세미콜론

 - 세미콜론(;)을 이용해서 문장을 끝내거나 한줄에 2개의 구문을 작성하지 않는다.

- 세미콜론 사용 지양

 

5. 줄 길이

 

- 최대 줄 길이는 80자 이다.

- 필요하다면 구문 양쪽에 괄호를 더할 수 있다.

foo_bar(self, width, height, color='black', design=None, x='foo',
emphasis=None, highlight=0)

    if (width == 0 and height == 0 and
        color == 'red' and emphasis == 'strong'):
x = ('This will build a very long long '
    'long long long long long long string')

 

6. 괄호

- 괄호를 적게 사용한다. 

- 5번과 같은 문장 연장이나 튜플을 나타내기 위한 상황이 아니면 사용하지 않는다.

 

올바른 예

if foo:
    bar()
while x:
    x = bar()
if x and y:
    bar()
if not x:
    bar()
# For a 1 item tuple the ()s are more visually obvious than the comma.
onesie = (foo,)
return foo
return spam, beans
return (spam, beans)
for (x, y) in dict.items(): ...

 

부적절한 예

if (x):
    bar()
if not(x):
    bar()
return (foo)

 

7. 들여쓰기 

- 코드를 작성할 때 4칸 들여쓰기 한다.

- 탭을 사용하거나 스페이스를 섞어서 사용해서도 안된다.

 

8. 빈 줄 

- 함수 선언이든 객체 선언이든 최상위 선언문과는 2개의 빈줄을 사이에 두어야 한다.

- 각 메소드 선언 또는 class 줄과 첫번째 메소드 선언 시 그 사이에는 빈줄이 있어야 한다.

class A:

    def meth1():
    ...
def cal1():
    ....
    
def cal2():
    ...

- def 줄 이후에는 빈줄이 없어야 한다.

- 함수와 메소드 사이에 개발자의 판단하에 적절하게 한 개의 빈 줄을 사용한다.

 

9. Whitespace

- 구두점 주변에 스페이스를 사용한다.

- 괄호, 중괄호, 대괄호 내부에는 화이트스페이스 없어야 한다.

 

올바른 예

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)

dict['key'] = list[index]

 

부적절한 예 

spam (1)

dict ['key'] = list [index]

 

- 형 지정이 존재한다면 매개변수의 기본값을 지정할 때 = 앞뒤에 공백을 사용 한다. 

 

올바른 예 

def complex(real, imag=0.0): return Magic(r=real, i=imag)
def complex(real, imag: float = 0.0): return Magic(r=real, i=imag)

 

부적절한 예 

def complex(real, imag = 0.0): return Magic(r = real, i = imag)
def complex(real, imag: float=0.0): return Magic(r = real, i = imag)

 

- 공백을 이용하여  연속된 여러 줄을 수직정렬하지 않는다. 

 

올바른 예 

foo = 1000  # comment
long_name = 2  # comment that should not be aligned

dictionary = {
    'foo': 1,
    'long_name': 2,
}

 

부적절한 예 

foo       = 1000  # comment
long_name = 2     # comment that should not be aligned

dictionary = {
    'foo'      : 1,
    'long_name': 2,
}

 

 

10. Strings

매개변수가 모두 문자열인 경우에도 f-string, format 메소드나 % 연산자를 포메팅한다.

문자열을 합치기 위해 % 또는 format을 사용하지 않는다.

 

올바른 예

x = a + b
x = '%s, %s!' % (imperative, expletive)
x = '{}, {}'.format(first, second)
x = 'name: %s; score: %d' % (name, n)
x = 'name: {}; score: {}'.format(name, n)
x = f'name: {name}; score: {n}'

 

부적절한 예

x = '%s%s' % (a, b)  # use + in this case
x = '{}{}'.format(a, b)  # use + in this case
x = first + ', ' + second
x = 'name: ' + name + '; score: ' + str(n)

단순히 문자열을 합치기 위함이면 + 를 사용하여 합니다.

또한 반복문에서 + 나 += 연산자를 사용하여 문자열을 누적하는 행위는 삼가하여야한다.  해당 연산자를 사용하여 문자열을 누적하는경우 제곱형태의 실행시간이 소요될 수 있다.

 

 

11. logging

파이썬에서는 파이썬 표준 라이브러리인 logging을 사용하여 로그를 남긴다.

로그를 남길 때 문자열이 인자로 요구되는 함수의 경우 아래의 규칙을 따른다.

  • 반드시 스트링 리터럴(f 스트링 아님)을 첫번째 인자, 패턴인자를 이후에 사용하여 호출하세요.
  • 일부 로깅방식의 경우 예상되지 않은 패턴문자열을 쿼리항목으로 이용합니다.
  • 또 로거가 필요없는 문자를 출력하는데에 시간을 낭비하지 않도록 방지합니다.

 

올바른 예 

 

  import tensorflow as tf
  logger = tf.get_logger()
  logger.info('TensorFlow Version is: %s', tf.__version__)

 

import os
  from absl import logging
  logging.info('Current $PAGER is: %s', os.getenv('PAGER', default=''))
  homedir = os.getenv('HOME')
  if homedir is None or not os.access(homedir, os.W_OK):
    logging.error('Cannot write to home directory, $HOME=%r', homedir)

 

잘못된 예 

 

 import os
  from absl import logging
  logging.info('Current $PAGER is:')
  logging.info(os.getenv('PAGER', default=''))
  homedir = os.getenv('HOME')
  if homedir is None or not os.access(homedir, os.W_OK):
    logging.error(f'Cannot write to home directory, $HOME={homedir!r}')

 

12 TODO Comments

 

임시적, 잠시 사용하려는 코드 또는 좋기는 하지만 완벽하지 않은 코드의 경우 TODO 주석을 사용한다.

 

TODO 주석은 대문자로 되어있는 TODO 문구로 시작하며 해당 코드에 대한 가장 높은 이해도를 가진 인물의 이름, 이메일 주소 또는 다른 신원구분 문구를 괄호안에 넣어 포함하여야 한다.

 

  • 이것 뒤에 무엇을 해야하는 지에 대한 내용을 추가합니다.
  • 목적은 TODO가 일관된 형식을 이용하여 추후 필요한 세부정보를 검색할 수 있어야 한다는 것입니다.
  • TODO 는 본인이 아닌 다른 개발자가 문제를 해결하겠다는 약속이 아닙니다.
  • 따라서 TODO 를 만드셨다면 거의 항상 작성한 본인의 이름이 들어가야 합니다.

 

# TODO(kl@gmail.com): Use a "*" here for string repetition.
# TODO(Zeke) Change this to use relations.

 

13 statements

  • 일반적으로 한 라인에는 오직 한 statement만 있어야 합니다.
  • 그러나, 테스트에 관한 statement 전체가 한 라인에 들어간다면 테스트 결과를 같은 줄에 둘 수 있습니다.
  • 특히 절대 try/except에서 try  except를 같은 라인에 둘 수 없고 if문에 else가 있지 않은 경우에는 가능합니다.

 

올바른 예 

 

if foo: bar(foo)

 

부적절한 예 

 

if foo: bar(foo)
else:   baz(foo)

try:               bar(foo)
except ValueError: baz(foo)

try:
    bar(foo)
except ValueError: baz(foo)