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

조회수 2338회

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

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 답변

  • 좋아요

    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"):
      

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)