Apakah Python mendukung hubungan arus pendek?

Jawaban:

304

Yap, baik hubung singkat andmaupun oroperator - lihat dokumen .

Alex Martelli
sumber
192

Hubungan arus pendek perilaku Operator and, or:

Pertama-tama mari kita mendefinisikan fungsi yang berguna untuk menentukan apakah sesuatu dieksekusi atau tidak. Fungsi sederhana yang menerima argumen, mencetak pesan dan mengembalikan input, tidak berubah.

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

Seseorang dapat mengamati perilaku hubung singkat Python dari and, oroperator dalam contoh berikut:

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

Catatan: Nilai-nilai berikut dianggap oleh penafsir sebagai false:

        False    None    0    ""    ()    []     {}

Perilaku hubungan pendek berfungsi: any(), all():

Python any()dan all()fungsinya juga mendukung hubungan arus pendek. Seperti yang ditunjukkan dalam dokumen; mereka mengevaluasi setiap elemen berurutan, sampai menemukan hasil yang memungkinkan keluar awal dalam evaluasi. Pertimbangkan contoh di bawah ini untuk memahami keduanya.

Fungsi ini any()memeriksa apakah ada elemen yang Benar. Itu berhenti mengeksekusi segera setelah Benar ditemui dan mengembalikan Benar.

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

Fungsi ini all()memeriksa semua elemen Benar dan berhenti mengeksekusi segera setelah False ditemukan:

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

Perilaku hubungan arus pendek dalam Perbandingan Dirantai:

Selain itu, dalam Python

Perbandingan dapat dirantai secara sewenang-wenang ; misalnya, x < y <= zsetara dengan x < y and y <= z, kecuali yang ydievaluasi hanya sekali (tetapi dalam kedua kasus ztidak dievaluasi sama sekali ketika x < yditemukan salah).

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

Edit:
Satu hal lagi yang menarik untuk catatan : - logis and,or operator di Python mengembalikan operan nilai bukan sebuah Boolean ( Trueatau False). Sebagai contoh:

Operasi x and ymemberikan hasilnyaif x is false, then x, else y

Tidak seperti dalam bahasa lain misalnya &&, ||operator dalam C yang mengembalikan 0 atau 1.

Contoh:

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

Demikian pula oroperator mengembalikan nilai paling kiri yang bool(value)== Truelain benar nilai paling salah (sesuai dengan perilaku hubungan pendek), contoh:

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

Jadi, bagaimana ini berguna? Salah satu contoh penggunaan yang diberikan dalam Python Praktis Oleh Magnus Lie Hetland:
Katakanlah pengguna seharusnya memasukkan namanya, tetapi dapat memilih untuk tidak memasukkan apa pun, dalam hal ini Anda ingin menggunakan nilai default '<unknown>'. Anda bisa menggunakan pernyataan if, tetapi Anda juga bisa menyatakan dengan sangat ringkas:

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

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

Dengan kata lain, jika nilai kembali dari raw_input benar (bukan string kosong), itu ditetapkan untuk nama (tidak ada perubahan); jika tidak, default '<unknown>'akan ditetapkan name.

Grijesh Chauhan
sumber
1
Minor quibble: Daftar eksplisit nilai falsy sedikit menyesatkan. Setiap jenis dapat memiliki satu atau lebih nilai falsy. Dengan konvensi, semua jenis numerik dengan nilai 0yang falsy (sehingga tidak hanya 0, itu 0.0, 0j, decimal.Decimal(0), fractions.Fraction(0), dll), seperti juga semua koleksi dengan panjang 0(jadi di atas apa yang Anda terdaftar, b''[Py3], u''[Py2] dan set()/ frozenset()adalah semua bawaan yang mengevaluasi sebagai kepalsuan), tetapi tipe yang ditentukan pengguna / pihak ketiga dapat menentukan sendiri (dengan __bool__[Py3] / __nonzero__[Py2] secara langsung, atau tidak langsung dengan mendefinisikan __len__).
ShadowRanger
@ShadowRanger di sini komentar Anda akan melengkapi jawaban saya. terima kasih telah menambahkan catatan ini.
Grijesh Chauhan
Juga, python mengevaluasi dua kondisi pendek yang dihubung-hubung, jika kemudian digunakan sebagai boolean ... kecuali jika mereka ada dalam pernyataan if, yang diistimewakan
Erik Aronesty
48

Iya. Coba yang berikut ini dengan juru bahasa python Anda:

dan

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

atau

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