Trong nhiều trường hợp, Python trông và hoạt động giống như tiếng Anh tự nhiên, nhưng đây là một trường hợp mà sự trừu tượng đó không thành công. Mọi người có thể sử dụng các manh mối ngữ cảnh để xác định rằng "Jon" và "Inbar" là các đối tượng được kết hợp với động từ "bằng", nhưng trình thông dịch Python có ý nghĩa hơn.
if name == "Kevin" or "Jon" or "Inbar":
về mặt logic tương đương với:
if (name == "Kevin") or ("Jon") or ("Inbar"):
Đối với người dùng Bob, tương đương với:
if (False) or ("Jon") or ("Inbar"):
Các or
nhà khai thác chọn đối số đầu tiên với một dương giá trị thật :
if ("Jon"):
Và vì "Jon" có giá trị sự thật dương, if
khối sẽ thực thi. Đó là nguyên nhân khiến "Quyền truy cập được cấp" được in bất kể tên đã cho.
Tất cả suy luận này cũng áp dụng cho biểu thức if "Kevin" or "Jon" or "Inbar" == name
. giá trị đầu tiên "Kevin"
, là true, vì vậy if
khối sẽ thực thi.
Có hai cách phổ biến để tạo điều kiện này một cách chính xác.
Sử dụng nhiều ==
toán tử để kiểm tra rõ ràng từng giá trị:
if name == "Kevin" or name == "Jon" or name == "Inbar":
Soạn một chuỗi các giá trị hợp lệ và sử dụng in
toán tử để kiểm tra tư cách thành viên:
if name in {"Kevin", "Jon", "Inbar"}:
Nhìn chung, hai phần thứ hai nên được ưu tiên hơn vì nó dễ đọc hơn và cũng nhanh hơn:
>>> 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
Đối với những người có thể muốn bằng chứng if a == b or c or d or e: ...
thực sự được phân tích cú pháp như thế này. Mô- ast
đun tích hợp cung cấp câu trả lời:
>>> 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=[])])"
>>>
Vì vậy, test
trong những if
vẻ tuyên bố như thế này:
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())
]
)
Như người ta có thể thấy, đó là các nhà điều hành boolean or
áp dụng cho nhiều values
, cụ thể là, a == b
và c
, d
và e
.