2 파이썬 언어 규칙
2.1 Lint
여러분의 코드에 pylint
를 사용하세요.
2.1.1 정의
pylint
는 파이썬 소스코드의 버그와 스타일 문제점을 찾는 툴입니다. 일반적으로 C나 C++와 같은 조금 덜 동적인 언어의 컴파일러에 의해 발견되는 문제점을 잡아냅니다. 파이썬의 동적인 특성 때문에, 몇몇 경고들은 부정확할 수 있습니다; 하지만, 이러한 거짓 경고는 매우 드물게 나타날 것입니다.
2.1.2 장점
오타, 변수를 할당하기 전 사용 등 놓치기 쉬운 부분들을 잡아냅니다.
2.1.3 단점
pylint
는 완벽하지 않습니다. 장점을 활용하기 위해선, 우리는 이를 때때로 1) 사용하고 2) 경고를 억제하거나 3) 향상시켜야 합니다.
2.1.4 결정
여러분의 코드에 반드시 pylint
를 사용하세요.
다른 이슈가 가려지지 않도록 경고가 적절하지 않다면 억제시키세요. 경고를 억제시키기 위해선, 여러분은 아래와 같이 한 줄 수준의 주석을 달면 됩니다.
pylint
경고들은 각각 상징적인 이름(empty-docstring
)으로 구글 특유의 경고는 g-
로 시작합니다.
상징적인 이름이 경고 억제의 사유를 충분히 설명하지 못한다면, 설명문을 다세요.
이러한 방법의 경고 억제는 우리가 쉽게 다시 억제 대상을 찾을 수 있도록 해줍니다.
여러분은 이렇게 pylint
의 경고 목록을 확인할 수 있습니다:
옛 형식인 pylint: disable-msg
대신 pylint: disable
를 사용하세요.
사용되지 않은 함수매개변수의 경고는 함수의 시작부에서 변수를 삭제함으로써 억제시킬 수 있습니다. 항상 왜 지우는지 주석을 다세요. "Unused."가 적당할 것입니다. 예를 들면:
이와 같은 경고를 억제하기 위한 다른 일반적인 방법들에는 '_
'를 사용되지 않는 함수매개변수의 식별자로 사용하기, 이름 앞에 'unused_
'를 붙이기, 또는 '_
'로 할당하기가 있습니다. 이러한 형식들은 더 이상 권장되지는 않습니다. 처음 두 break 호출자는 함수매개변수를 이름으로 전달하는 반면, 마지막은 그 함수매개변수가 실제로 사용되지 않는다고 강요하지 않습니다.
2.2 Imports
2.2.1 정의
한 모듈에서 다른 모듈로 코드를 공유하기 위한 재사용 매커니즘입니다.
2.2.2 장점
네임스페이스 관리 규약은 간단합니다. 각 식별자의 소스는 일관된 방식으로 표시됩니다. x.Obj
은 객체 Obj
가 x
라는 모듈 안에 정의되어 있음을 의미합니다.
2.2.3 단점
모듈 이름이 여전히 충돌할 가능성이 있습니다. 일부 모듈 이름은 불편하게 깁니다.
2.2.4 결정
import x
는 패키지나 모듈을 임포트할 때 사용하세요.from x import y
는x
가 패키지 접두사이고y
가 접두사가 없는 모듈 이름일 때 사용하세요.from x import y as z
는y
라는 이름을 가지고 있는 두 개의 모듈을 임포트해야 하거나y
가 불편할 정도로 길 때 사용하세요.import y as z
는z
가 표쥰 약어(예를 들어,numpy
의np
)일 때만 사용하세요.
예를 들면 sound.effects.echo
모듈은 아래와 같이 임포트될 것입니다.
임포트를 할 때는 상대적인 이름을 사용하지 마세요. 모듈이 동일한 패키지에 있더라도 전체 패키지 이름을 사용하세요. 이렇게 하면 의도하지 않게 패키지를 두 번 임포트하는 것을 방지할 수 있습니다.
2.3 Packages
모듈의 전체 경로를 이용해서 각 모듈을 임포트하세요.
2.3.1 장점
제작자가 의도하지 않은 방법으로 모듈 경로를 지정하는 것으로 발생할 수 있는 모듈 이름의 충돌이나 부정확한 모듈 경로를 임포트 하는 것을 방지합니다.
2.3.2 단점
패키지 계층 구조를 복제해야 하기 때문에 코드를 전개하기 더 힘들어집니다. 현대 전개 매커니즘에서 별 문제는 압니다.
2.3.3 결정
모든 코드에서 각 모듈은 전체 패키지의 이름으로 임포트해야 합니다.
임포트는 아래와 같아야 합니다:
예:
아니오: (이 파일이 jodie.py
파일도 함께 있는 doctor/who
에 있다고 가정합니다)
메인 바이너리가 위치하고 있는 디렉토리가 일부 환경에서 그렇다 하더라도 sys.path
경로 안에 있다고 가정하면 안 됩니다. 이런 경우, import jodie
가 써드파티나 최상위 패키지의 jodie
를 나타내는 것으로 가정해야 합니다, 로컬에 있는 jodie.py
가 아닙니다.
2.4 Exception
예외처리는 허용되지만 조심히 사용해야 합니다.
2.4.1 정의
예외처리는 에러나 다른 예외적인 상황을 다루기 위해 코드 블록의 정상적인 컨트롤 플로우를 벗어나는 것을 의미합니다.
2.4.2 장점
정상적인 코드의 컨트롤 플로우는 에러 취급 코드로 인해 어수선하지 않습니다. 특정 상황이 발생하면 다수의 프레임을 컨트롤 플로우가 건너뛰도록 허용도 합니다, 예를 들어, N 번 중첩된 함수에서 에러 코드를 전달하지 않고 한 스텝에 반환하기.
2.4.3 단점
컨트롤 플로우의 혼란을 야기할 수 있습니다. 라이브러리를 콜 할 때 에러 케이스들을 놓치기 쉽습니다.
2.4.4 결정
예외처리는 반드시 특정 상황에 따라서 사용되야 합니다:
예외처리는 이렇게 일으키세요:
raise MyError('Error message')
또는raise MyError()
.두 개의 매개변수를 사용하는 형식
(raise MyError, 'Error message')
을 사용하지 마세요.
이치에 맞게 내장 예외처리 클래스를 사용하세요. 예를 들면, 여러분이 음수를 전달했지만 양수를 기대했을 때는 ValueError
를 일으키세요. 공용 API 매개변수 값의 유효성 검사에서 assert
구문을 사용하지 마세요. assert
는 내부적 정확성을 보장하기 위해 사용되며, 정확한 사용을 강요하거나 예상치 못한 이벤트가 발생했음을 나타내기 위해 사용되는 것이 아닙니다. 후자에서 예외처리가 필요한 경우, raise
구문을 사용하세요. 예를 들면:
라이브러리나 패키지는 스스로의 예외처리를 정의할 수 있습니다. 그러고자 할 때는 반드시 기존에 존재하는 예외처리 클래스로부터 상속을 받아야 합니다. 예외처리 이름은
Error
로 끝나며 말을 더듬게 (foo.FooError
) 하지 않아야 합니다.여러분이 예외처리를 다시 일으키려고 하거나 (에러 메세지 출력을) 쓰레드 가장 바깥쪽 코드 블록에서 하는게 아니라면, catch-all
except
구문, 또는 catchException
또는Standard Error
를 절대 사용하지 마세요. 파이썬은 이런 관련 사항과except:
에 대해서는 매우 관대해서 잘못 스펠된 이름, sys.exit() 콜, Ctrl+C 방해, 뜻밖의 실패와 여러분이 잡고 싶지 않은 다른 모든 종류의 예외처리를 정말 다 잡아낼 것입니다.try/except
블록 내 코드의 양을 최소화하세요.try
의 바디가 크면 클수록, 코드 라인에 따라 의해 여러분이 예상하지 않은 예외처리를 일으킬 가능성이 커집니다. 그러한 경우,try/except
블록은 진짜 에러를 숨기게 됩니다.try
블록에서 예외처리가 일어났든지 안 났든지 코드를 실행시키기 위해finally
절을 사용하세요. 파일 닫기, 같은 정리에 자주 유용하게 사용됩니다.예외처리 값을 잡을 때, 콤마 대신에
as
를 사용하세요. 예를 들면:
2.5 Global variables
전역변수 사용을 피하세요.
2.5.1 정의
모듈 레벨에서나 클래스의 속성으로 선언된 변수.
2.5.2 장점
간혹 유용합니다.
2.5.3 단점
전역변수의 할당은 모듈이 처음 임포트될 때 완료되기 때문에, 임포트하는 동안 모듈의 동작을 바꿀 수 있습니다.
2.5.4 결정
전역변수의 사용을 피하세요.
2.6 Nested/Local/Inner Classes and Functions
중첩된 지역함수나 클래스가 지역변수로의 엑세스를 차단하는 용도로 사용된다면 괜찮습니다. 내부 클래스는 괜찮습니다.
2.6.1 정의
클래스는 메서드, 함수, 또는 클래스 안에서 정의될 수 있습니다. 함수는 메서드나 함수 안에서 정의될 수 있습니다. 중첩된 함수는 둘러싸인 스코프에서 정의된 변수에 읽기전용으로 엑세스할 수 있습니다.
2.6.2 장점
2.6.3 단점
중첩되거나 지역 클래스는 pickle로 다룰 수 없습니다. 중첩된 함수와 클래스는 직접적으로 테스트할 수 없습니다. 중첩은 여러분의 외부 함수를 더욱 길고 읽기 어렵게 만듭니다.
2.6.4 결정
이러한 것들은 몇 가지 주의사항으로 괜찮습니다. 지역 값으로의 엑세스를 차단하는 경우가 아니라면 중첩된 함수나 클래스의 사용을 피하세요. 함수를 모듈 사용자에게서 숨기기 위해 중첩시키지 마세요. 대신, 테스트에서 계속 엑세스할 수 있도록 모듈 레벨에서 이름 앞에 _
를 붙이세요.
2.7 Comprehensions & Generator Expressions
간단한 경우에 사용하는 것은 괜찮습니다.
2.7.1 정의
리스트, 딕셔너리, 그리고 세트 컴프리헨션 및 제너레이터 표현식은 기존 루프, map()
, filter()
, 또는 lambda
를 사용하지 않고 컨테이너 타입이나 이리테이터를 만들 수 있는 간결하고 효율적인 방법을 제공합니다.
2.7.2 장점
간단한 컴프리헨션은 다른 딕셔너리, 리스트, 또는 세트 생성 테크닉보다 명확하고 간단할 수 있습니다. 제너레이터 표현식은 리스트 생성을 완전히 피해가기 때문에, 매우 효율적일 수 있습니다.
2.7.3 단점
복잡한 컴프리헨션이나 제너레이터 표현식은 읽기 어려울 수 있습니다.
2.7.4 결정
간단한 경우에 사용하는 것은 괜찮습니다. 각 부분은 한 줄: 매핑 표현식, for
절, 필터 표현식에 적합해야 합니다. 다수의 for
절 또는 필터 표현식은 허용되지 않습니다. 더 복잡해지는 경우엔 대신 루프를 사용하세요.
2.8 Default Iterators and Operators
리스트, 딕셔너리, 그리고 파일과 같이 기본 이터레이터나 연산자를 지원하는 타입에 이 것들을 사용하세요.
2.8.1 정의
딕셔너리와 리스트 같은, 컨테이너 타입들은, 기본 이터레이터와 멤버쉽 테스트 연산자(“in” and “not in”)를 정의합니다.
2.8.2 장점
기본 이터레이터와 연산자는 단순하고 효율적입니다. 별도의 메소드를 콜하지 않고도, 연산을 직접 표현합니다. 기본 연산자를 사용는 함수는 제네릭입니다. 연산을 지원하는 어떤 타입과도 사용될 수 있습니다.
2.8.3 단점
메소드의 이름(예를 들어, has_key()는 딕셔너리를 의미합니다)을 읽어서는 객체의 타입을 말할 수 없습니다. 이것도 장점입니다.
2.8.4 결정
리스트, 딕셔너리, 그리고 파일과 같이 기본 이터레이터나 연산자를 지원하는 타입에 이 것들을 사용하세요. 빌트-인 타입도 이터레이터 메소드를 정의합니다. 리스트를 반환하는 메소드에 이러한 방법을 선호합니다. 단, 반복하는 동안 컨테이너를 변경해서는 안 됩니다. 필요한 경우가 아니라면 절대 dict.iter*()
와 같은 Python 2 특정 반복 메소드를 사용하지 마세요.
2.9 Generators
필요에 띠리 제너레이터를 사용하세요.
2.9.1 정의
제너레이터 함수는 매번 yield 구문을 실행할 때 마다 값을 산출하는 이터레이터를 반환합니다. 값을 산출하면, 다음 값이 필요할 때까지 제너레이터 함수의 런타임 상태는 일시 중단됩니다.
2.9.2 장점
더 간단한 코드입니다, 왜냐하면 각 콜에 대해 로컬 변수와 컨트롤 플로우의 상태가 유지되기 때문입니다. 제너레이터는 전체 값 목록을 한 번에 생성하는 함수보다 적은 메모리를 사용합니다.
2.9.3 단점
없습니다.
2.9.4 결정
좋습니다. 제너레이터 함수의 독스트링에서 "Return:" 대신 "Yield:"를 사용하세요.
2.10 Lambda Function
한 줄 용도로는 괜찮습니다.
2.10.1 정의
Lambda는 구문과는 반대로 표현식으로 익명 함수를 정의합니다. map()
와 filter()
같은 고차 함수의 콜백이나 연산자를 정의하는데 자주 사용됩니다.
2.10.2 장점
편리합니다.
2.10.3 단점
지역함수보다 읽고 디버깅하기가 어렵습니다. 이름이 없다는 것은 스택 추적을 이해하기 더 어렵다는 것을 의미합니다. 함수가 표현식만을 포함하여야 하기 때문에 표현력이 제한됩니다.
2.10.4 결정
곱셈과 같은 일반적인 연산에서는, lambda 함수 대신에 operator
모듈의 함수를 사용하세요. 예를 들면, lambda x, y: x * y
대신 operator.mul
를 사용하세요.
2.11 Conditional Expressions
2.11.1 정의
2.11.2 장점
2.11.3 단점
2.11.4 결정
Last updated
Was this helpful?