it-swarm-id.com

jika A vs jika A tidak Tidak ada:

Bisakah saya menggunakan:

if A:

dari pada

if A is not None:

Yang terakhir tampaknya sangat bertele-tele. Apakah ada perbedaan?

129
rbairos

Pernyataan

if A:

akan memanggil A.__nonzero__() (lihat nama metode khusus dokumentasi) dan menggunakan nilai balik dari fungsi itu. Berikut ringkasannya:

object.__nonzero__(self)

Dipanggil untuk menerapkan pengujian nilai kebenaran dan operasi bawaan bool(); harus mengembalikan False atau True, atau setara bilangan bulatnya 0 atau 1. Ketika metode ini tidak didefinisikan, __len__() dipanggil, jika didefinisikan, dan objek dianggap benar jika hasilnya nol. Jika suatu kelas tidak mendefinisikan __len__() atau __nonzero__(), semua instansnya dianggap benar.

Di samping itu,

if A is not None:

membandingkan hanya referensi A dengan None untuk melihat apakah itu sama atau tidak.

129
Greg Hewgill

Seperti yang ditulis dalam PEP8 :

  • Perbandingan dengan lajang seperti Tidak ada harus selalu dilakukan dengan 'is' atau 'not', tidak pernah operator kesetaraan .

    Selain itu, berhati-hatilah menulis "jika x" ketika Anda benar-benar bermaksud "jika x tidak ada" - mis. saat menguji apakah variabel atau argumen yang default ke Tidak ada diatur ke beberapa nilai lain. Nilai lain mungkin memiliki tipe (seperti wadah) yang bisa salah dalam konteks boolean!

47
scraplesh
if x: #x is treated True except for all empty data types [],{},(),'',0 False, and None

jadi tidak sama dengan

if x is not None # which works only on None
20
Abdul Muneer

Banyak fungsi kembali Tidak ada jika tidak ada hasil yang sesuai. Misalnya, metode .first() query SQLAlchemy mengembalikan Tidak ada jika tidak ada baris dalam hasilnya. Misalkan Anda memilih nilai yang mungkin mengembalikan 0 dan perlu tahu apakah itu sebenarnya 0 atau apakah kueri tidak memiliki hasil sama sekali.

Idi umum adalah untuk memberikan argumen opsional fungsi atau metode nilai default Tidak ada, dan kemudian untuk menguji nilai yang menjadi Tidak ada untuk melihat apakah itu ditentukan. Sebagai contoh:

def spam(eggs=None):
    if eggs is None:
        eggs = retrievefromconfigfile()

bandingkan dengan:

def spam(eggs=None):
    if not eggs:
        eggs = retrievefromconfigfile()

Dalam yang terakhir, apa yang terjadi jika Anda memanggil spam(0) atau spam([])? Fungsi ini akan (secara keliru) mendeteksi bahwa Anda belum memberikan nilai untuk eggs dan akan menghitung nilai default untuk Anda. Mungkin itu bukan yang Anda inginkan.

Atau bayangkan metode seperti "kembalikan daftar transaksi untuk akun yang diberikan". Jika akun tidak ada, itu mungkin mengembalikan Tidak Ada. Ini berbeda dengan mengembalikan daftar kosong (yang berarti "akun ini ada tetapi belum mencatat transaksi).

Akhirnya, kembali ke basis data. Ada perbedaan besar antara NULL dan string kosong. String kosong biasanya mengatakan "ada nilai di sini, dan nilai itu sama sekali tidak ada". NULL mengatakan "nilai ini belum dimasukkan."

Dalam setiap kasus tersebut, Anda ingin menggunakan if A is None. Anda memeriksa nilai tertentu - Tidak ada - bukan hanya "nilai apa pun yang terjadi pada False".

16
Kirk Strauser

Mereka melakukan hal yang sangat berbeda .

Di bawah ini memeriksa apakah A memiliki apa pun kecuali nilai False, [], None, '' dan 0. Ia memeriksa nilai dari A.

if A:

Di bawah ini memeriksa apakah A adalah objek yang berbeda dari Tidak Ada. Ia memeriksa dan membandingkan referensi (alamat memori) A dan None.

if A is not None:

PEMBARUAN: Penjelasan lebih lanjut

Sering kali keduanya tampaknya melakukan hal yang sama sehingga banyak orang menggunakannya secara bergantian - itu ide yang sangat buruk. Alasan keduanya memberikan hasil yang sama berkali-kali dengan kebetulan murni karena optimisasi dari interpreter/compiler seperti interning atau sesuatu yang lain.

Dengan adanya optimasi tersebut, bilangan bulat dan string dengan nilai yang sama berakhir menggunakan ruang memori yang sama. Itu mungkin menjelaskan mengapa dua string terpisah bertindak seolah-olah mereka sama.

> a = 'test'
> b = 'test'
> a is b
True
> a == b
True

Hal-hal lain tidak berperilaku sama ..

> a = []
> b = []
> a is b
False
> a == b
True

Kedua daftar jelas memiliki ingatan mereka sendiri. Anehnya tuple berperilaku seperti string.

> a = ()
> b = ()
> a is b
True
> a == b
True

Mungkin ini karena tuple dijamin tidak berubah, jadi masuk akal untuk menggunakan kembali memori yang sama.

Intinya adalah bahwa Anda tidak dapat bergantung pada kebetulan . Hanya karena dukun seperti bebek itu tidak berarti itu bebek. Gunakan is dan == tergantung pada apa yang ingin Anda periksa. Hal-hal ini bisa sulit untuk di-debug karena is berbunyi seperti prosa yang sering kita lewati saja.

10
Pithikos

jika A: akan terbukti salah jika A adalah 0, False, atau None, yang dapat menyebabkan hasil yang tidak diinginkan.

7
keflavich

Sebagian besar panduan yang pernah saya lihat menyarankan agar Anda gunakan

jika sebuah:

kecuali Anda memiliki alasan untuk lebih spesifik.

Ada beberapa perbedaan kecil. Ada nilai selain Tidak ada yang mengembalikan False, misalnya daftar kosong, atau 0, jadi pikirkan apa yang sebenarnya Anda uji.

6
Colin Coghill

Tidak ada yang merupakan nilai khusus dalam Python yang biasanya menunjuk variabel tidak diinisialisasi. Untuk menguji apakah A tidak memiliki nilai tertentu yang Anda gunakan:

if A is not None

Nilai Falsey adalah kelas objek khusus dengan Python (mis. False, []). Untuk menguji apakah A palsu, gunakan:

if not A

Jadi, kedua ungkapan itu tidak sama Dan Anda sebaiknya tidak memperlakukannya sebagai sinonim.


P.S. Tidak ada yang juga salah, jadi ungkapan pertama menyiratkan yang kedua. Tetapi yang kedua mencakup nilai-nilai falsey lain selain Tidak Ada. Sekarang ... jika Anda dapat memastikan bahwa Anda tidak dapat memiliki nilai falsey lain selain Tidak ada dalam A, maka Anda dapat mengganti ekspresi pertama dengan yang kedua.

5
mircealungu

Itu tergantung pada konteksnya.

Saya menggunakan if A: ketika saya mengharapkan A menjadi semacam koleksi, dan saya hanya ingin menjalankan blok jika koleksi tidak kosong. Hal ini memungkinkan penelepon untuk melewati koleksi apa pun yang berperilaku baik, kosong atau tidak, dan membuatnya melakukan apa yang saya harapkan. Itu juga memungkinkan None dan False untuk menekan eksekusi blok, yang kadang-kadang nyaman untuk memanggil kode.

OTOH, jika saya berharap A menjadi beberapa objek yang sepenuhnya arbitrer tetapi bisa saja default ke None, maka saya selal menggunakan if A is not None, karena kode panggilan dapat dengan sengaja memberikan referensi ke suatu tempat kosong koleksi, string kosong, atau tipe numerik bernilai 0, atau boolean False, atau beberapa instance kelas yang kebetulan salah dalam konteks boolean.

Dan di sisi lain, jika saya berharap A menjadi beberapa hal yang lebih spesifik (misalnya instance dari kelas yang akan saya panggil metode), tetapi bisa saja default ke None, dan saya menganggap konversi boolean default menjadi menjadi properti kelas yang saya tidak keberatan menerapkan pada semua subclass, maka saya hanya akan menggunakan if A: untuk menyelamatkan jari-jari saya beban yang sangat berat untuk mengetik 12 karakter tambahan.

4
Ben

Yang pertama lebih Pythonic (kode ideomatik yang lebih baik), tetapi tidak akan mengeksekusi blok jika A adalah False (bukan None).

3
Borealid

Saya membuat file bernama test.py dan menjalankannya pada penerjemah. Anda dapat mengubah apa yang Anda inginkan, untuk menguji dengan pasti bagaimana keadaan di balik layar.

import dis

def func1():

    matchesIterator = None

    if matchesIterator:

        print( "On if." );

def func2():

    matchesIterator = None

    if matchesIterator is not None:

        print( "On if." );

print( "\nFunction 1" );
dis.dis(func1)

print( "\nFunction 2" );
dis.dis(func2)

Ini adalah perbedaan assembler:

Sumber:

>>> import importlib
>>> reload( test )

Function 1
  6           0 LOAD_CONST               0 (None)
              3 STORE_FAST               0 (matchesIterator)

  8           6 LOAD_FAST                0 (matchesIterator)
              9 POP_JUMP_IF_FALSE       20

 10          12 LOAD_CONST               1 ('On if.')
             15 PRINT_ITEM
             16 PRINT_NEWLINE
             17 JUMP_FORWARD             0 (to 20)
        >>   20 LOAD_CONST               0 (None)
             23 RETURN_VALUE

Function 2
 14           0 LOAD_CONST               0 (None)
              3 STORE_FAST               0 (matchesIterator)

 16           6 LOAD_FAST                0 (matchesIterator)
              9 LOAD_CONST               0 (None)
             12 COMPARE_OP               9 (is not)
             15 POP_JUMP_IF_FALSE       26

 18          18 LOAD_CONST               1 ('On if.')
             21 PRINT_ITEM
             22 PRINT_NEWLINE
             23 JUMP_FORWARD             0 (to 26)
        >>   26 LOAD_CONST               0 (None)
             29 RETURN_VALUE
<module 'test' from 'test.py'>
2
user

python> = 2.6,

jika kita menulis seperti

if A:

akan menghasilkan peringatan seperti,

FutureWarning: Perilaku metode ini akan berubah di versi mendatang. Gunakan tes khusus 'len (elem)' atau 'elem bukan None'.

Jadi bisa kita gunakan

if A is not None:
1
normalUser