google python guide

About_work·2023년 1월 27일
0

python clean code

목록 보기
6/11

주로 다른 부분 (과거 또는 현재)

Line length

  • 최대 80줄
  • 예외
    • 커멘트(주석)에 있는 URLs, pathname, long flags
    • Long string module level constants not containing whitespace that would be inconvenient to split across lines such as URLs or pathnames.
      • Pylint disable comments. (e.g.: # pylint: disable=invalid-name
  • baskslash line 점프를 쓰지 마라! except for with statements requiring three or more context managers. (괄호 권장)

Imports

  • 패키지와 모듈만 import 하라.
  • 개별적 class나 function은 import 하지 마라.
  • (repo root 부터 시작하는) full package name 으로 import하라.

Imports formatting

import collections
import queue
import sys

from absl import app
from absl import flags
import bs4
import cryptography
import tensorflow as tf

from book.genres import scifi
from myproject.backend import huxley
from myproject.backend.hgwells import time_machine
from myproject.backend.state_machine import main_loop
from otherproject.ai import body
from otherproject.ai import mind
from otherproject.ai import soul
  • import는 별도의 lines에서 처리되어야 한다.
    • typing과 collections.abc imports 는 예외이다.
  • import 순서
    • Python future import(=future) statements
    • Python 표준 library
    • 서드파티 module or package
    • 코드 repository sub-package

Indentation

  • 4 space 를 쓰고, tab을 쓰지 말라.

자주 참고하는 부분

Comprehensions & Generator Expressions

  • 복잡한 경우는 가독성이 떨어지기 떄문에 사용하지 않지만, 그 외의 경우는 권장한다.

Type annotations

  • type annotation을 적용하다 보면, 무거운 import를 막기 위해 모듈화가 향상됨
    • 타입/인터페이스 정의와 구현 부분이 분리 됨.
  • Forward Declaration: 같은 모듈 내에 정의 안된 클래스에 대한 type annotations
from __future__ import annotations

class MyClass:
  def __init__(self, stack: Sequence[MyClass], item: OtherClass) -> None:

class OtherClass:
  ...

# 또는 

class MyClass:
  def __init__(self, stack: Sequence['MyClass'], item: 'OtherClass') -> None:

class OtherClass:
  ...
  • Type aliases
_LossAndGradient = tuple[tf.Tensor, tf.Tensor]
ComplexTFMap = Mapping[str, _LossAndGradient]
  • Typing variables
# Annotated Assignments
a: Foo = SomeUndecoratedFunction()
# Type Comments
a = SomeUndecoratedFunction()  # type: Foo

Naming

피해야할 naming

  • 1글자 이름 피해라. (아래는 예외이다.)
    • counter나 iterator (i, j, k, v)
    • try/except statements 에서 exception identifier인 e
    • file handle f
    • private TypeVars with no constraints (e.g. _T, _U, _V)
  • 불필요하게 variable의 type을 명시하는 이름은 피하라.

Naming Conventions

  • 클래스이름: 대문자
  • 모듈 이름: 소문자
  • _abc: 모듈 변수와 함수의 보호를 지원

Mathematical Notation

  • 수학적으로 무거운 코드는 짧은 변수명을 쓰자.
    • 대신 comment(주석) 이나 docstring에 source of all naming convention을 남겨라.
    • 명확히 naming conventions를 문서화하라.

Guido`s 추천 가이드

Unused variables

  • 사용하지 않는 argument가 있으면, 아래와 같이 하고 comment 를 포함하라.
def viking_cafe_order(spam: str, beans: str, eggs: Optional[str] = None) -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
  • 다른 가능한 형태로는
    • ‘_’ as the identifier for the unused argument or
    • prefixing the argument name with ‘unused_’
    • assigning them to ‘_’. These forms are allowed but no longer encouraged

Strings

  • Use an f-string, the % operator, or the format method for formatting strings. (consistency 유지가 중요)
  • Tips: f-string 사용 리뷰 중 익숙하지 않은 notation 발견 시 (예, "{name!r}"), python string doc 확인
  • Avoid using the + and += operators to accumulate a string within a loop.
  • Instead, add each substring to a list and ''.join the list after the loop terminates, or write each substring to an io.StringIO buffer.

Logging

  • For logging functions that expect a pattern-string as their first argument: Always call them with a string literal (not an f-string!) (Error 메시지 아님)

Blank Lines

  • top-level definitions 사이에 2줄 간격 (top level definition이 함수나 class 정의가 되게 하라.)
  • mehod 정의 사이는 1줄 간격
  • 클래스의 docstring과 첫 method 사이에 1줄 간격
  • def line 뒤에는 간격 주지 마라.

기타 Tips

  • numpy/tensor 함수 호출 시, in/out shape 에 대한 comment(주석) 추가
  • numpy/tensor array 관련(주로 테스트 케이스의 예제 상수)하여 yapf로 수정된 결과가 가독성이 떨어지면 yapf inline disable 사용
# yapf: disable
FOO = {
    # ... some very large, complex data literal.
}
BAR = [
    # ... another large data literal.
]
# yapf: enable


BAZ = {
    (1, 2, 3, 4),
    (5, 6, 7, 8),
    (9, 10, 11, 12),
}  # yapf: disable
profile
새로운 것이 들어오면 이미 있는 것과 충돌을 시도하라.

0개의 댓글