왜 'a == b or c or d'는 항상 참인가요?


저는 지금 인증되지 않은 사용자로부터의 접근을 막는 보안 시스템을 작성하고 있습니다.

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과 같이 로직을 반대로 구성도해보았지만, 여전히 결과는 동일합니다.

  • 2016년 05월 29일에 작성됨

조회수 91


1 답변


좋아요
0
싫어요
채택취소하기

많은 경우에서 파이썬은 자연어처럼 보이고 그와 같이 행동하지만, 이 경우는 그렇지 않은 경우들 중 하나입니다. 사람들은 "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문 안의 코드 블록이 실행됩니다.


질문하신 분께서 의도하신 조건문을 만들기 위해서는 다음과 같은 두가지의 일반적인 방법이 존재합니다.

  1. 각각의 값을 비교할 수 있도록 여러개의 == 연산자를 사용하는 방법 :

    if name == "Kevin" or name == "Jon" or name == "Inbar":
    
  2. 비교할 값들을 순서쌍으로 구성하여, in 연산자를 이용하는 방법 :

    if name in ("Kevin", "Jon", "Inbar"):
    
  • 2016년 05월 30일에 작성됨

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close