Python có hỗ trợ ngắn mạch không?


Câu trả lời:



192

Hành vi ngắn mạch trong toán tử and, or:

Trước tiên chúng ta hãy xác định một hàm hữu ích để xác định xem một cái gì đó có được thực thi hay không. Một hàm đơn giản chấp nhận một đối số, in một thông báo và trả về đầu vào, không thay đổi.

>>> def fun(i):
...     print "executed"
...     return i
... 

Người ta có thể quan sát các hành vi ngắn circuiting của Python của and, orcác nhà khai thác trong ví dụ sau:

>>> fun(1)
executed
1
>>> 1 or fun(1)    # due to short-circuiting  "executed" not printed
1
>>> 1 and fun(1)   # fun(1) called and "executed" printed 
executed
1
>>> 0 and fun(1)   # due to short-circuiting  "executed" not printed 
0

Lưu ý: Các giá trị sau được trình thông dịch coi là sai:

        False    None    0    ""    ()    []     {}

Hành vi ngắn mạch trong chức năng: any(), all():

Python any()và các all()chức năng cũng hỗ trợ ngắn mạch. Như thể hiện trong các tài liệu; họ đánh giá từng yếu tố của một chuỗi theo thứ tự, cho đến khi tìm thấy kết quả cho phép thoát ra sớm trong đánh giá. Xem xét các ví dụ dưới đây để hiểu cả hai.

Hàm any()kiểm tra nếu có phần tử nào là True. Nó dừng thực thi ngay khi gặp True và trả về True.

>>> any(fun(i) for i in [1, 2, 3, 4])   # bool(1) = True
executed
True
>>> any(fun(i) for i in [0, 2, 3, 4])   
executed                               # bool(0) = False
executed                               # bool(2) = True
True
>>> any(fun(i) for i in [0, 0, 3, 4])
executed
executed
executed
True

Hàm all()kiểm tra tất cả các thành phần là True và dừng thực thi ngay khi gặp phải Sai:

>>> all(fun(i) for i in [0, 0, 3, 4])
executed
False
>>> all(fun(i) for i in [1, 0, 3, 4])
executed
executed
False

Hành vi ngắn mạch trong So sánh xích:

Ngoài ra, bằng Python

So sánh có thể được xâu chuỗi tùy ý ; ví dụ, x < y <= ztương đương với x < y and y <= z, ngoại trừ chỉ yđược đánh giá một lần (nhưng trong cả hai trường hợp zkhông được đánh giá ở tất cả khi x < yđược phát hiện là sai).

>>> 5 > 6 > fun(3)    # same as:  5 > 6 and 6 > fun(3)
False                 # 5 > 6 is False so fun() not called and "executed" NOT printed
>>> 5 < 6 > fun(3)    # 5 < 6 is True 
executed              # fun(3) called and "executed" printed
True
>>> 4 <= 6 > fun(7)   # 4 <= 6 is True  
executed              # fun(3) called and "executed" printed
False
>>> 5 < fun(6) < 3    # only prints "executed" once
executed
False
>>> 5 < fun(6) and fun(6) < 3 # prints "executed" twice, because the second part executes it again
executed
executed
False

Chỉnh sửa:
Một điểm thú vị hơn cần lưu ý : - Các logic and,or toán tử trong Python trả về giá trị của toán hạng thay vì Boolean ( Truehoặc False). Ví dụ:

Hoạt động x and ycho kết quảif x is false, then x, else y

Không giống như trong các ngôn ngữ khác &&, ví dụ , các ||toán tử trong C trả về 0 hoặc 1.

Ví dụ:

>>> 3 and 5    # Second operand evaluated and returned 
5                   
>>> 3  and ()
()
>>> () and 5   # Second operand NOT evaluated as first operand () is  false
()             # so first operand returned 

Tương tự ortoán tử trả về hầu hết giá trị bên trái mà giá trị bool(value)== Truekhác phải hầu hết giá trị sai (theo hành vi ngắn mạch), ví dụ:

>>> 2 or 5    # left most operand bool(2) == True
2    
>>> 0 or 5    # bool(0) == False and bool(5) == True
5
>>> 0 or ()
()

Vì vậy, làm thế nào là hữu ích? Một ví dụ sử dụng được đưa ra trong Python thực tế của Magnus Lie Hetland:
Giả sử người dùng phải nhập tên của họ, nhưng có thể chọn không nhập gì, trong trường hợp bạn muốn sử dụng giá trị mặc định '<unknown>'. Bạn có thể sử dụng một câu lệnh if, nhưng bạn cũng có thể nói những điều rất ngắn gọn:

In [171]: name = raw_input('Enter Name: ') or '<Unkown>'
Enter Name: 

In [172]: name
Out[172]: '<Unkown>'

Nói cách khác, nếu giá trị trả về từ raw_input là true (không phải là chuỗi rỗng), thì nó được gán cho tên (không có gì thay đổi); mặt khác, mặc định '<unknown>'được gán cho name.


1
Phân minh nhỏ: Danh sách rõ ràng các giá trị giả là hơi sai lệch. Bất kỳ loại có thể có một hoặc nhiều giá trị giả. Theo quy ước, tất cả các loại số với giá trị 0là falsy (vì vậy nó không chỉ là 0, đó là 0.0, 0j, decimal.Decimal(0), fractions.Fraction(0), vv), cũng như tất cả các bộ sưu tập với chiều dài 0(để trên đầu trang của những gì bạn liệt kê, b''[Py3], u''[Py2] và set()/ frozenset()là tất cả các công cụ xây dựng được đánh giá là giả mạo), nhưng các loại do người dùng / bên thứ ba xác định có thể xác định trực tiếp (với __bool__[Py3] / __nonzero__[Py2] hoặc gián tiếp bằng cách xác định __len__).
ShadowRanger

@ShadowRanger ở đây bình luận của bạn sẽ hoàn thành câu trả lời của tôi. cảm ơn vì đã thêm ghi chú này
Grijesh Chauhan

Ngoài ra, trăn đúp đánh giá lại ngắn mạch điều kiện, nếu sau đó được sử dụng như các phép toán luận ... trừ khi họ đang ở trong một câu lệnh if, được priviliged: gist.github.com/earonesty/08e9cbe083a5e0583feb8a34cc538010
Erik Aronesty

48

Đúng. Hãy thử những điều sau trong trình thông dịch python của bạn:

>>>False and 3/0
False
>>>True and 3/0
ZeroDivisionError: integer division or modulo by zero

hoặc là

>>>True or 3/0
True
>>>False or 3/0
ZeroDivisionError: integer division or modulo by zero
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.