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) , 많은 상황에서는 키가 존재하지 않는 경우보다 복잡한 연산이 필요할 수 있습니다