Python Language
파이썬 안티 패턴
수색…
과열 예외 조항
예외는 강력하지만 단 한 개의 과도한 except 절은 한 줄로 모두 제거 할 수 있습니다.
try: res = get_result() res = res[0] log('got result: %r' % res) except: if not res: res = '' print('got exception')
이 예제는 반 패턴의 3 가지 증상을 보여줍니다.
-
except
예외없이 유형 (5 호선)을 포함 심지어 건강한 예외 잡을 것KeyboardInterrupt
. 그러면 일부 경우 프로그램이 종료되지 않습니다. - except 블록은 오류를 다시 발생시키지 않습니다. 이는
get_result
내에서 예외가 발생get_result
또는res
가 빈 목록인지 여부를 알 수 없음을 의미합니다. - 최악의 경우, 결과가 비어 있다고 걱정한다면 우리는 훨씬 더 심각한 결과를 초래했습니다.
get_result
가 실패하면res
는 완전히 설정되지 않은 상태로 유지되고 except 블록의res
에 대한 참조는NameError
발생시켜 원래 오류를 완전히 마스킹합니다.
항상 처리하려고하는 예외의 유형에 대해 생각하십시오. 예외 페이지에 읽기 권한을 부여 하고 기본 예외가 존재하는지 확인하십시오.
다음은 위의 예제의 고정 된 버전입니다.
import traceback try: res = get_result() except Exception: log_exception(traceback.format_exc()) raise try: res = res[0] except IndexError: res = '' log('got result: %r' % res)
우리는보다 구체적인 예외를 잡아 필요한 곳을 재발행합니다. 몇 줄이긴하지만 무한히 정확합니다.
프로세서 집약적 인 기능으로 도약하기 전에 살펴보기
프로그램은 프로세서를 많이 사용하는 함수를 여러 번 호출하여 시간을 낭비 할 수 있습니다.
입력의 경우에 정수를 반환 예를 들어, 다음과 같은 기능이 걸릴 value
하나 밖에 생산할 수 None
:
def intensive_f(value): # int -> Optional[int]
# complex, and time-consuming code
if process_has_failed:
return None
return integer_output
그리고 그것은 다음과 같은 방법으로 사용될 수 있습니다 :
x = 5
if intensive_f(x) is not None:
print(intensive_f(x) / 2)
else:
print(x, "could not be processed")
print(x)
이 방법이 효과가 있지만 intensive_f
를 호출하면 코드가 실행되는 시간이 두 배로 늘어납니다. 더 좋은 해결책은 미리 함수의 반환 값을 얻는 것입니다.
x = 5
result = intensive_f(x)
if result is not None:
print(result / 2)
else:
print(x, "could not be processed")
그러나, 예를 들어 예외를 사용 하는 것이 더 명확하고 가능성이있는 pythonic 방법 입니다.
x = 5
try:
print(intensive_f(x) / 2)
except TypeError: # The exception raised if None + 1 is attempted
print(x, "could not be processed")
여기에 임시 변수가 필요하지 않습니다. assert
문을 사용하고 대신 AssertionError
를 catch하는 것이 좋습니다.
사전 키
이것이 발견 될 수있는 일반적인 예는 사전 키에 액세스하는 것입니다. 예를 들어 비교해보십시오 :
bird_speeds = get_very_long_dictionary()
if "european swallow" in bird_speeds:
speed = bird_speeds["european swallow"]
else:
speed = input("What is the air-speed velocity of an unladen swallow?")
print(speed)
와:
bird_speeds = get_very_long_dictionary()
try:
speed = bird_speeds["european swallow"]
except KeyError:
speed = input("What is the air-speed velocity of an unladen swallow?")
print(speed)
첫 번째 예제는 사전을 두 번보아야하며 긴 사전이므로 매번 그렇게하는 데 시간이 오래 걸릴 수 있습니다. 두 번째는 사전을 통해 한 번만 검색하면되기 때문에 많은 프로세서 시간을 절약 할 수 있습니다.
이것에 대한 대안은 dict.get(key, default)
를 사용하는 dict.get(key, default)
, 많은 상황에서는 키가 존재하지 않는 경우보다 복잡한 연산이 필요할 수 있습니다