파이썬에서 변수가 없음, 참 또는 거짓인지 어떻게 테스트해야합니까?


147

세 가지 중 하나를 반환 할 수있는 기능이 있습니다.

  • 성공 ( True)
  • 실패 ( False)
  • 스트림 읽기 / 파싱 오류 ( None)

내 질문은 True또는 False에 대해 테스트하지 않으면 결과가 무엇인지 어떻게 확인 해야하는지입니다. 아래는 내가 현재하고있는 방법입니다.

result = simulate(open("myfile"))
if result == None:
    print "error parsing stream"
elif result == True: # shouldn't do this
    print "result pass"
else:
    print "result fail"

실제로 == True부품 을 제거하는 것보다 간단 합니까 아니면 tri-bool 데이터 유형을 추가해야합니다. simulate외부 프로그램이 오류로 처리하기를 원하면 로그를 기록하고 계속 하기 때문에 함수가 예외를 던지는 것을 원하지 않습니다 .


당신은 잘못된 질문을하고 있습니다; "실패"와 "오류 구문 분석 스트림"의 차이점이 무엇인지, 그 의미는 무엇이며, 결과는 무엇이며, 발신자가 취할 행동은 무엇입니까? 각 경우에 (통과, 실패, 구문 분석 오류)?
John Machin

나는 전력 시스템을 시뮬레이트하고 있습니다. 사람들이 집에서 전력을 잃으면 그것은 실패입니다. 시뮬레이션 파일을 읽을 수 없으면 완전히 다른 종류의 오류입니다.
James Brooks

2
simulate함수 내에서 나는 모든 예외를 포착합니다. 시뮬레이터에서 발생하는 나머지 프로그램 실행을 중지하고 다음 요소를 처리하는 것을 원하지 않습니다. 그러나 그 대답으로 인해 마음이 바뀌 었습니다.
제임스 브룩스

1
@ 제임스 브룩스 : 그렇습니다. 이것이 시도 / 제외 처리에 관한 것입니다. simulate잡을 수 있고 재 시도 할 수있는 것이 있다면 좋습니다. 그러나 "실패"하면 반환하지 않아야합니다 None. 그것을 호출 한 스크립트에 예외를 제기해야합니다. 어느 쪽이든 simulate이루어집니다. 리턴 None은 적절한 예외를 발생 시키거나 예외가 simulate처리를 위해 호출 스크립트로 전파되도록 허용하는 것만 큼 도움이되지 않습니다 .
S.Lott

1
@ 제임스 except Exception:대신 사용하십시오. 이와 함께, 모든 "진짜"오류를 잡아 WarningStopIteration. 그것은 수 KeyboardInterruptSystemExit생각을 통해. 당신이 정말로 그것들을 잡으려면, 다른 외부 시도 / 제외 또는 의도가 명확하게 문서화되어있는 다른 구조를 사용하는 것이 가장 좋습니다. 이것은 "오류"가 아니기 때문입니다. (하지만 아마도 귀하의 경우에는 당신이 정말로 잡아 모든 하시겠습니까, 심지어는 Ctrl-C를 또는 방지 ... "거의 절대"말을하지 않았다 sys.exit()종료에서, 등)
피터 한센

답변:


119

예외를 두려워하지 마십시오! 프로그램을 로그하고 계속 진행하는 것은 다음과 같이 쉽습니다.

try:
    result = simulate(open("myfile"))
except SimulationException as sim_exc:
    print "error parsing stream", sim_exc
else:
    if result:
        print "result pass"
    else:
        print "result fail"

# execution continues from here, regardless of exception or not

이제 오류 / 오류 없음이 충분히 유익하지 않은 경우를 대비하여 시뮬레이션 방법에서 정확히 무엇이 잘못되었는지에 대해 훨씬 더 풍부한 유형의 알림을받을 수 있습니다.


동의했다. 위의 명백히 더 인기있는 솔루션 (C 코드와 너무 많이 냄새가 나는 것)보다 훨씬 더 많은 pythonic.
Brandon

7
@Brandon 동의하지 않습니다. 이 코드는 위의 솔루션 (또는 아래의 개선 된 버전)보다 길고 더 나빠 읽기 쉽지 않습니다. 더 많은 들여 쓰기, 더 다른 진술-후자가 더 인기있는 이유를 추측하십시오 ... ;-) 왜 노력하려고합니까? 그것이 더 어색한 코드로 이어지는 경우 'Pythonic'...?
Rolf Bartstra

이제 "오류 구문 분석 스트림"대신 역 추적을 인쇄하면 투표권이 있습니다.
CivFan

좋아, 당신은 어쨌든 내 투표권을 얻었지만 나는 다음과 같은 인쇄를 의미했습니다 traceback.format_exc() . 이 SO 답변을 참조하십시오.
CivFan

11
많은 사람들이 제목 질문에 대한 답을 찾기 위해이 페이지를 방문 할 것입니다. 우리 대부분은 "예외를 두려워하지 마십시오!" 우리의 상황과 관련이 없습니다 True, False 및 None 만 테스트하면됩니다. 귀하의 제안 된 대안이 어떤 경우에는 유효하지만 질문에 대한 답변을 포함시키는 것이 가장 좋습니다.
hugesupersuperman

163
if result is None:
    print "error parsing stream"
elif result:
    print "result pass"
else:
    print "result fail"

간단하고 명시 적으로 유지하십시오. 물론 사전을 사전 정의 할 수 있습니다.

messages = {None: 'error', True: 'pass', False: 'fail'}
print messages[result]

simulate더 많은 리턴 코드를 포함하도록 함수를 수정하려는 경우이 코드를 유지 보수하는 것이 약간 문제가 될 수 있습니다.

simulate또한, 구문 분석 오류에 예외를 발생시킬 수있는 경우에 당신도 여기를 잡거나 수준을 전파 할 수 및 인쇄 비트가 한 줄 경우-else 문으로 감소 될 것입니다 것입니다.


1
후자는 True 또는 False에 대한 일종의 명시 적 테스트입니다.
Peter Eisentraut

1
물론, 이것이 가능한 반환 값이라는 것을 알면 그것이 문제라고 생각하지 않습니다.
SilentGhost

뿐만 아니라 빠른 비트를 것 같다
SilentGhost

a = '
foo'a

17

절대, 절대, 절대 말하지 마

if something == True:

못. if 문에 대한 중복 조건 규칙으로 중복 지정된 것을 반복해서 반복하기 때문에 미친 짓입니다.

더 이상, 여전히, 절대, 절대, 절대 말하지 마십시오

if something == False:

당신은 있습니다 not. 자유롭게 사용하십시오.

마지막으로, a == None비효율적입니다. 마십시오 a is None. None특별한 싱글 톤 객체입니다. 단 하나만있을 수 있습니다. 해당 객체가 있는지 확인하십시오.


3
평등에 대한 테스트 True는 중복되지 않습니다 (나는 그것이 합리적이지 않다는 데 동의하지만). 실제로 할 수있는 __eq__다른 특별한 방법을 호출 할 수 있습니다 .
Scott Griffiths

5
@Scott Griffiths : 좋은 지적입니다. 그것은 참으로 끔찍한 시나리오입니다. 실제로 그러한 경우, 프로그램은 그러한 흑 마법없이 간단하게 삭제하고 처음부터 다시 작성해야하는 방식으로 우리의 근본적인 기대를 위반합니다.
S.Lott

78
'절대로, 절대, 절대로'...? 그러나 그렇지 않은 if something == True경우가 있습니다 if something(예 : non-boolean) something. true로 평가 2==True하지만 2true로 평가합니다. None==False거짓하지만 not None사실이다!
Rolf Bartstra

9
-1 @Rolf Bartstra의 말이 사실이기 때문에이 답변은 오도되고 완전히 틀립니다. 이 경우에, 당신이 말하는 것을 적용 할 수 있습니다.
HelloGoodbye

3
-1. 에 대한 0이 아니거나 비어 있지 않거나 길이가 0이 아닌 값이에서 something반환 True되기 때문 bool(something)입니다. 이 경우 something값이 Trueie 인지 확인하려는 경우에만 bool. 그런 다음 if something == TrueIMO 를해야 합니다.
Samarth Shah

2

나는 상황이 있어도, 그것을 강조하고 싶은 if expr :사람이 있는지 확인하고 싶어하기 때문에 충분하지 않습니다 expr이다 True와에서 단 한 차이가 0/ None무엇이든, / is에서 선호 될 == S. 로트는 피하는 했나요 같은 이유는== None .

그것은 실제로 약간 더 효율적이며, 케이크 위에 체리가 있고, 더 인간이 읽을 수 있습니다.

In [1]: %timeit (1 == 1) == True
38.1 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [2]: %timeit (1 == 1) is True
33.7 ns ± 0.141 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

1
벤치 마크를 한 번 실행할 수 없으며 벤치 마크가 다른 벤치 마크보다 효율적이라고 말할 수는 없습니다. 평균적으로 동작하는 방식을 보려면 여러 번 (10.000) 실행하십시오. \
user1767754

1

예외를 던지는 것이 귀하의 상황에 더 좋은 아이디어라고 생각합니다. 대안은 튜플을 반환하는 시뮬레이션 방법입니다. 첫 번째 항목은 상태이고 두 번째 항목은 결과입니다.

result = simulate(open("myfile"))
if not result[0]:
  print "error parsing stream"
else:
  ret= result[1]

1
반환 튜플은 일반적으로 튜플 포장 풀기와 잘
어울립니다

2
그러나 코드가 의미가 없으므로 False반환되면 인쇄 'error parsing stream'됩니다.
SilentGhost

시뮬레이트 메소드는 ret이 False 또는 True 인 경우 (False, "anything") 또는 (True, ret)을 리턴해야합니다.
kgiannakakis

2
글쎄, 당신은 당신의 논리에 맞게 출력 값을 재정의하고 있습니다, 그것은 설명이 명확하지 않습니다
SilentGhost
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.