왜 'a == b or c or d'는 항상 참인가요?
조회수 2337회
저는 지금 인증되지 않은 사용자로부터의 접근을 막는 보안 시스템을 작성하고 있습니다.
import sys
print("Hello. Please enter your name:")
name = sys.stdin.readline().strip()
if name == "Kevin" or "Jon" or "Inbar":
print("Access granted.")
else:
print("Access denied.")
예상대로 위 코드는 인증된 사용자의 접근을 허용하지만, 인증되지 않은 사용자의 접근 또한 허용하고 있습니다.
Hello. Please enter your name:
Bob
Access granted.
왜 이런 현상이 나타나는 건가요? 분명히 저는 name
이 Kevin, Jon, 혹은 Inbar와 동일할 경우에만 접근을 허용하고 있는데 말이죠. if "Kevin" or "Jon" or "Inbar" == name
과 같이 로직을 반대로 구성도해보았지만, 여전히 결과는 동일합니다.
1 답변
-
많은 경우에서 파이썬은 자연어처럼 보이고 그와 같이 행동하지만, 이 경우는 그렇지 않은 경우들 중 하나입니다. 사람들은 "Jon"과 "Inbar"가 "같다"라는 동사에 걸리는 목적어라고 문맥적으로 추론할 수 있지만, 파이썬 인터프리터는 원문 그대로를 받아드립니다.
if name == "Kevin" or "Jon" or "Inbar":
는 논리적으로 아래와 같고 :
if (name == "Kevin") or ("Jon") or ("Inbar"):
이 때, Bob이라는 이름의 유저의 경우, 아래와 같이 치환됩니다 :
if (False) or ("Jon") or ("Inbar"):
이때
or
연산자는 참값을 지니는 진릿값을 지니는 첫번째 인자를 선택하고 :if ("Jon"):
"Jon"은 참값을 지니고 있기 때문에,
if
문 안의 코드 블록이 실행이 됩니다. 이로인해 입력되는 이름값과 무관하게 항상 접근을 허용하는 것입니다.if "Kevin" or "Jon" or "Inbar" == name
구문 또한 마찬가지로"Kevin"
이 참값을 지니기 때문에,if
문 안의 코드 블록이 실행됩니다.
질문하신 분께서 의도하신 조건문을 만들기 위해서는 다음과 같은 두가지의 일반적인 방법이 존재합니다.
각각의 값을 비교할 수 있도록 여러개의
==
연산자를 사용하는 방법 :if name == "Kevin" or name == "Jon" or name == "Inbar":
비교할 값들을 순서쌍으로 구성하여,
in
연산자를 이용하는 방법 :if name in ("Kevin", "Jon", "Inbar"):
댓글 입력