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.)
isadalah 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 Noneatau di mana Anda ingin melindungi terhadap benda yang pecah ketika dibandingkan dengan None.
Nonememiliki 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 otherkebetulan None.
isseperti Java ==. Python ==adalah seperti Jawa .equals(). Tentu saja ini hanya membantu jika Anda tahu Java.
isseperti ===(sangat sama), dan sebaliknya is notseperti !==(tidak persis sama).
is notoperator tunggal atau hanya meniadakan hasil isseperti 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 dismisssemua mengacu pada objek yang sama dalam memori. Anda hanya membuat satu Buttonobjek, dan ketiga variabel merujuk ke objek yang satu ini. Kami mengatakan bahwa cancel,, closedan dismisssemua 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 aagar 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, adan 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 unicodepasti 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, adan 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 objectdan 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)
Noneadalah 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 Nonedapat 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 issama dengan ==. Sebagian besar tidak.
()dan 1secara inheren bukan lajang.
-NSMALLNEGINTS <= n <= NSMALLPOSINTS) dan tuple kosong adalah lajang. Memang tidak didokumentasikan atau dijamin, tetapi tidak mungkin berubah.