대부분의 경우 Python은 자연스러운 영어처럼 보이고 동작하지만 이는 추상화가 실패하는 경우입니다. 사람들은 문맥 단서를 사용하여 "Jon"과 "Inbar"가 동사 "equals"에 결합 된 객체인지 결정할 수 있지만, Python 인터프리터는 더 문자 그대로 생각합니다.
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"}:
일반적으로 두 번째는 읽기 쉽고 빠르기 때문에 선호되어야합니다.
>>> import timeit
>>> timeit.timeit('name == "Kevin" or name == "Jon" or name == "Inbar"', setup="name='Inbar'")
0.4247764749999945
>>> timeit.timeit('name in {"Kevin", "Jon", "Inbar"}', setup="name='Inbar'")
0.18493307199999265
if a == b or c or d or e: ...
실제로 이와 같이 구문 분석 되는 증명을 원하는 사람들을 위해 . 내장 ast
모듈은 다음과 같은 답을 제공합니다.
>>> import ast
>>> ast.parse("if a == b or c or d or e: ...")
<_ast.Module object at 0x1031ae6a0>
>>> ast.dump(_)
"Module(body=[If(test=BoolOp(op=Or(), values=[Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]), Name(id='c', ctx=Load()), Name(id='d', ctx=Load()), Name(id='e', ctx=Load())]), body=[Expr(value=Ellipsis())], orelse=[])])"
>>>
소위 test
의 if
이 같은 문 외모 :
BoolOp(
op=Or(),
values=[
Compare(
left=Name(id='a', ctx=Load()),
ops=[Eq()],
comparators=[Name(id='b', ctx=Load())]
),
Name(id='c', ctx=Load()),
Name(id='d', ctx=Load()),
Name(id='e', ctx=Load())
]
)
사람이 볼 수 있듯이, 상기 부울 연산자의 or
여러 적용 values
, 즉 a == b
과 c
, d
와 e
.