Saya telah melihat beberapa contoh kode seperti ini:
if not someobj:
#do something
Tapi saya bertanya-tanya mengapa tidak melakukan:
if someobj == None:
#do something
Apakah ada perbedaan? Apakah yang satu memiliki keunggulan dibandingkan yang lain?
X != None
?Jawaban:
Dalam tes pertama, Python mencoba untuk mengkonversi objek ke
bool
nilai jika belum. Secara kasar, kami menanyakan objek: apakah Anda bermakna atau tidak? Ini dilakukan dengan menggunakan algoritma berikut:Jika objek memiliki
__nonzero__
metode khusus (seperti halnya numerik built-in,int
danfloat
), ia memanggil metode ini. Itu harus mengembalikanbool
nilai yang kemudian langsung digunakan, atauint
nilai yang dianggapFalse
jika sama dengan nol.Jika tidak, jika objek memiliki
__len__
metode khusus (seperti halnya wadah built-in,list
,dict
,set
,tuple
, ...), itu panggilan metode ini, mengingat wadahFalse
jika kosong (panjang adalah nol).Jika tidak, objek dianggap
True
kecuali kecualiNone
dalam hal ini, itu dianggapFalse
.Dalam tes kedua, objek dibandingkan untuk kesetaraan
None
. Di sini, kita bertanya objek, "Apakah Anda sama dengan nilai lainnya ini?" Ini dilakukan dengan menggunakan algoritma berikut:Jika objek memiliki
__eq__
metode, itu disebut, dan nilai kembali kemudian dikonversi kebool
nilai dan digunakan untuk menentukan hasil dariif
.Kalau tidak, jika objek memiliki
__cmp__
metode, itu disebut. Fungsi ini harus mengembalikanint
urutan kedua objek yang ditunjukkan (-1
jikaself < other
,0
jikaself == other
,+1
jikaself > other
).Jika tidak, objek tersebut dibandingkan untuk identitas (mis. Mereka merujuk ke objek yang sama, seperti yang dapat diuji oleh
is
operator).Ada tes lain yang mungkin menggunakan
is
operator. Kami akan bertanya objek, "Apakah Anda objek khusus ini?"Secara umum, saya akan merekomendasikan untuk menggunakan tes pertama dengan nilai-nilai non-numerik, untuk menggunakan tes untuk kesetaraan ketika Anda ingin membandingkan objek yang sifatnya sama (dua string, dua angka, ...) dan untuk memeriksa identitas hanya ketika menggunakan nilai sentinel (
None
artinya tidak diinisialisasi untuk bidang anggota sebagai contoh, atau saat menggunakangetattr
atau__getitem__
metode).Untuk meringkas, kami memiliki:
sumber
Ini sebenarnya adalah praktik yang buruk. Sekali waktu, itu dianggap OK untuk dengan santai memperlakukan None dan False sebagai serupa. Namun, karena Python 2.2 ini bukan kebijakan terbaik.
Pertama, ketika Anda melakukan tes
if x
atauif not x
semacamnya, Python harus secara implisit dikonversix
ke boolean. Aturan untukbool
fungsi menggambarkan rakit hal-hal yang Salah; yang lainnya Benar. Jika nilai x tidak benar untuk memulai, konversi implisit ini sebenarnya bukan cara yang paling jelas untuk mengatakan sesuatu.Sebelum Python 2.2, tidak ada fungsi bool, jadi itu bahkan kurang jelas.
Kedua, Anda seharusnya tidak benar-benar mengujinya
== None
. Anda harus menggunakanis None
danis not None
.Lihat PEP 8, Panduan Gaya untuk Kode Python .
Ada berapa lajang? Lima:
None
,True
,False
,NotImplemented
danEllipsis
. Karena Anda benar-benar tidak mungkin untuk menggunakanNotImplemented
atauEllipsis
, dan Anda tidak akan pernah mengatakannyaif x is True
(karenaif x
jauh lebih jelas), Anda hanya akan pernah mengujiNone
.sumber
Karena
None
bukan satu-satunya hal yang dianggap salah.False
,0
,()
,[]
,{}
Dan""
semua berbeda dariNone
, sehingga Anda dua potongan kode yang tidak setara.Selain itu, pertimbangkan hal berikut:
if object:
adalah tidak cek kesetaraan.0
,()
,[]
,None
,{}
, Dll yang semua berbeda satu sama lain, tetapi mereka semua mengevaluasi ke False.Ini adalah "keajaiban" di balik ekspresi hubungan arus pendek seperti:
yang merupakan singkatan untuk:
walaupun Anda benar-benar harus menulis:
sumber
PEP 8 - Style Guide untuk Kode Python merekomendasikan penggunaan adalah atau tidak jika Anda menguji untuk Tidak-ness
Di sisi lain jika Anda menguji lebih dari ketiadaan, Anda harus menggunakan operator boolean.
sumber
Jika Anda bertanya
yang __nonzero__ metode spam yang dipanggil. Dari manual Python:
Jika Anda bertanya
yang __eq__ metode spam yang dipanggil dengan argumen ada .
Untuk informasi lebih lanjut tentang kemungkinan penyesuaian, lihat dokumentasi Python di https://docs.python.org/reference/datamodel.html#basic-customization
sumber
Kedua perbandingan ini memiliki tujuan yang berbeda. Yang pertama memeriksa nilai boolean dari sesuatu, yang kedua memeriksa identitas dengan nilai Tidak ada.
sumber
Untuk satu contoh pertama lebih pendek dan terlihat lebih bagus. Seperti posting lainnya, apa yang Anda pilih juga tergantung pada apa yang benar-benar ingin Anda lakukan dengan perbandingan.
sumber
Jawabannya adalah, tergantung".
Saya menggunakan contoh pertama jika saya menganggap 0, "", [] dan False (daftar tidak lengkap) setara dengan Tidak ada dalam konteks ini.
sumber
Secara pribadi, saya memilih pendekatan yang konsisten di seluruh bahasa: Saya lakukan
if (var)
(atau setara) hanya jika var dinyatakan sebagai boolean (atau didefinisikan seperti itu, di C kami tidak memiliki jenis tertentu). Saya bahkan mengawali variabel-variabel ini denganb
(jadibVar
sebenarnya) untuk memastikan saya tidak akan sengaja menggunakan tipe lain di sini.Saya tidak terlalu suka casting implisit ke boolean, apalagi ketika ada banyak aturan kompleks.
Tentu saja, orang akan tidak setuju. Beberapa lebih jauh, saya melihat
if (bVar == true)
dalam kode Java di tempat kerja saya (terlalu berlebihan untuk seleraku!), Yang lain suka sintaksis terlalu banyak kompak, pergiwhile (line = getNextLine())
(terlalu ambigu bagi saya).sumber