Dalam komentar pada pertanyaan ini , saya melihat pernyataan yang merekomendasikan penggunaan
result is not None
vs.
result != None
Saya bertanya-tanya apa perbedaannya, dan mengapa yang satu lebih direkomendasikan daripada yang lain?
Dalam komentar pada pertanyaan ini , saya melihat pernyataan yang merekomendasikan penggunaan
result is not None
vs.
result != None
Saya bertanya-tanya apa perbedaannya, dan mengapa yang satu lebih direkomendasikan daripada yang lain?
Jawaban:
==
adalah ujian kesetaraan . Ia memeriksa apakah sisi kanan dan sisi kiri adalah benda yang sama (sesuai dengan __eq__
atau__cmp__
metode.)
is
adalah tes identitas . Ia memeriksa apakah sisi kanan dan sisi kiri adalah objek yang sama. Tidak ada panggilan metode yang dilakukan, objek tidak dapat memengaruhiis
operasi.
Anda menggunakan is
(dan is not
) untuk lajang, seperti None
, di mana Anda tidak peduli dengan objek yang mungkin ingin berpura-pura None
atau di mana Anda ingin melindungi terhadap benda yang pecah ketika dibandingkan dengan None
.
None
memiliki beberapa metode dan hampir tidak memiliki atribut. Jika __eq__
pengujian Anda mengharapkan suatu metode atau atribut, itu mungkin pecah. def __eq__( self, other ): return self.size == other.size
. Misalnya, akan pecah jika other
kebetulan None
.
is
seperti Java ==
. Python ==
adalah seperti Jawa .equals()
. Tentu saja ini hanya membantu jika Anda tahu Java.
is
seperti ===
(sangat sama), dan sebaliknya is not
seperti !==
(tidak persis sama).
is not
operator tunggal atau hanya meniadakan hasil is
seperti internal not foo is bar
?
Pertama, biarkan saya membahas beberapa istilah. Jika Anda hanya ingin pertanyaan Anda dijawab, gulir ke bawah ke "Menjawab pertanyaan Anda".
Identitas objek : Saat Anda membuat objek, Anda dapat menetapkannya ke variabel. Anda kemudian dapat juga menugaskannya ke variabel lain. Dan satu lagi.
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
Dalam hal ini, cancel
, close
, dan dismiss
semua mengacu pada objek yang sama dalam memori. Anda hanya membuat satu Button
objek, dan ketiga variabel merujuk ke objek yang satu ini. Kami mengatakan bahwa cancel
,, close
dan dismiss
semua mengacu pada objek yang identik ; yaitu, mereka merujuk ke satu objek tunggal.
Kesetaraan objek : Ketika Anda membandingkan dua objek, Anda biasanya tidak peduli bahwa itu merujuk ke objek yang sama persis di memori. Dengan persamaan objek, Anda dapat menentukan aturan Anda sendiri untuk membandingkan dua objek. Ketika Anda menulis if a == b:
, Anda pada dasarnya mengatakan if a.__eq__(b):
. Ini memungkinkan Anda menentukan __eq__
metode a
agar Anda dapat menggunakan logika perbandingan sendiri.
Dasar Pemikiran: Dua objek memiliki data yang sama persis, tetapi tidak identik. (Mereka bukan objek yang sama dalam memori.) Contoh: String
>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True
Catatan: Saya menggunakan string unicode di sini karena Python cukup pintar untuk menggunakan kembali string biasa tanpa membuat yang baru di memori.
Di sini, saya memiliki dua string unicode, a
dan b
. Mereka memiliki konten yang sama persis, tetapi mereka bukan objek yang sama dalam memori. Namun, ketika kami membandingkannya, kami ingin mereka membandingkan yang sama. Apa yang terjadi di sini adalah bahwa objek unicode telah mengimplementasikan __eq__
metode ini.
class unicode(object):
# ...
def __eq__(self, other):
if len(self) != len(other):
return False
for i, j in zip(self, other):
if i != j:
return False
return True
Catatan: __eq__
aktif unicode
pasti diterapkan lebih efisien daripada ini.
Dasar Pemikiran: Dua objek memiliki data yang berbeda, tetapi dianggap objek yang sama jika beberapa data utama adalah sama. Contoh: Sebagian besar tipe data model
>>> import datetime
>>> a = Monitor()
>>> a.make = "Dell"
>>> a.model = "E770s"
>>> a.owner = "Bob Jones"
>>> a.warranty_expiration = datetime.date(2030, 12, 31)
>>> b = Monitor()
>>> b.make = "Dell"
>>> b.model = "E770s"
>>> b.owner = "Sam Johnson"
>>> b.warranty_expiration = datetime.date(2005, 8, 22)
>>> a is b
False
>>> a == b
True
Di sini, saya punya dua monitor Dell, a
dan b
. Mereka memiliki merek dan model yang sama. Namun, mereka tidak memiliki data yang sama atau objek yang sama dalam memori. Namun, ketika kami membandingkannya, kami ingin mereka membandingkan yang sama. Apa yang terjadi di sini adalah objek Monitor mengimplementasikan __eq__
metode.
class Monitor(object):
# ...
def __eq__(self, other):
return self.make == other.make and self.model == other.model
Saat membandingkan None
, selalu gunakan is not
. Tidak ada yang tunggal dalam Python - hanya ada satu contoh dalam memori.
Dengan membandingkan identitas , ini dapat dilakukan dengan sangat cepat. Python memeriksa apakah objek yang Anda maksud memiliki alamat memori yang sama dengan objek global None - perbandingan dua angka yang sangat, sangat cepat.
Dengan membandingkan kesetaraan , Python harus mencari apakah objek Anda memiliki __eq__
metode. Jika tidak, itu akan memeriksa setiap superclass mencari __eq__
metode. Jika menemukan satu, Python menyebutnya. Ini sangat buruk jika __eq__
metode ini lambat dan tidak segera kembali ketika melihat bahwa objek lainnyaNone
.
Apakah Anda tidak menerapkannya __eq__
? Kemudian Python mungkin akan menemukan __eq__
metode object
dan menggunakannya sebagai gantinya - yang hanya memeriksa identitas objek saja.
Saat membandingkan sebagian besar hal lain dengan Python, Anda akan menggunakannya !=
.
Pertimbangkan yang berikut ini:
class Bad(object):
def __eq__(self, other):
return True
c = Bad()
c is None # False, equivalent to id(c) == id(None)
c == None # True, equivalent to c.__eq__(None)
None
adalah singleton, oleh karena itu perbandingan identitas akan selalu berfungsi, sedangkan objek dapat memalsukan perbandingan kesetaraan melalui .__eq__()
.
None
, tetapi perilaku yang salah tentang hal itu None
dapat terjadi sebagai efek samping dari penerapan kesetaraan terhadap jenis lainnya. Ini bukan implikasi keamanan, tetapi implikasi kebenarannya.
>>> () adalah () Benar >>> 1 adalah 1 Benar >>> (1,) == (1,) Benar >>> (1,) adalah (1,) Salah >>> a = (1,) >>> b = a >>> a adalah b Benar
Beberapa objek adalah lajang, dan karenanya is
sama dengan ==
. Sebagian besar tidak.
()
dan 1
secara inheren bukan lajang.
-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) dan tuple kosong adalah lajang. Memang tidak didokumentasikan atau dijamin, tetapi tidak mungkin berubah.