Yorumunda bu soruya , benim kullandığım önerilen bir bildiri gördü
result is not None
vs
result != None
Farkın ne olduğunu ve neden birinin diğerine önerilebileceğini merak ediyordum?
Yorumunda bu soruya , benim kullandığım önerilen bir bildiri gördü
result is not None
vs
result != None
Farkın ne olduğunu ve neden birinin diğerine önerilebileceğini merak ediyordum?
Yanıtlar:
==
Bir olan eşitlik testi . Sağ tarafın ve sol tarafın eşit nesneler olup olmadığını kontrol eder ( __eq__
veya __cmp__
yöntemlerine göre ).
is
bir kimlik testidir . Sağ taraf ile sol tarafın aynı nesne olup olmadığını kontrol eder. Hiçbir yöntem çağrısı yapılmaz, nesneler is
işlemi etkileyemez .
Gibi davranmak isteyebileceğiniz veya kıyaslandığında kırılan nesnelere karşı korumak istediğiniz nesneler hakkında umursamadığınız tektonlar için is
(ve is not
) kullanırsınız .None
None
None
None
birkaç yöntemi vardır ve neredeyse hiç özniteliği yoktur. Senin Eğer __eq__
deney yöntemi veya niteliği beklenen, bu bozabilir. def __eq__( self, other ): return self.size == other.size
. Örneğin, eğer other
olursa kırılacaktır None
.
is
Java'nın gibidir ==
. Python'lar ==
Java gibidir .equals()
. Tabii ki bu sadece Java'yı biliyorsanız yardımcı olur.
is
gibidir ===
(çok eşit) ve tersine is not
gibidir !==
(tam olarak eşit değildir).
is not
Tek bir operatör mü yoksa sadece is
dahili gibi bir sonucu not foo is bar
mu olumsuz etkiliyor ?
İlk olarak, birkaç terimi gözden geçirmeme izin verin. Sorunuzun yanıtlanmasını istiyorsanız, "Sorunuzu cevaplama" bölümüne gidin.
Nesne kimliği : Bir nesne oluşturduğunuzda, nesneyi bir değişkene atayabilirsiniz. Daha sonra başka bir değişkene de atayabilirsiniz. Ve başka.
>>> button = Button()
>>> cancel = button
>>> close = button
>>> dismiss = button
>>> print(cancel is close)
True
Bu durumda, cancel
, close
ve dismiss
tüm bellekte aynı nesneyi. Yalnızca bir Button
nesne oluşturdunuz ve her üç değişken de bu nesneyi ifade ediyor. Biz demek cancel
, close
ve dismiss
tüm atıfta özdeş nesneler; yani, tek bir nesneye atıfta bulunurlar.
Nesne eşitliği : İki nesneyi karşılaştırdığınızda, genellikle bellekteki tam olarak aynı nesneyi ifade ettiğini umursamazsınız . Nesne eşitliği ile iki nesnenin karşılaştırması için kendi kurallarınızı tanımlayabilirsiniz. Yazarken if a == b:
, aslında diyorsun if a.__eq__(b):
. Bu , kendi karşılaştırma mantığınızı kullanabilmeniz için __eq__
üzerinde bir yöntem tanımlamanızı sağlar a
.
Gerekçe: İki nesne aynı verilere sahiptir, ancak aynı değildir. (Bellekteki aynı nesne değildirler.) Örnek: Dizeler
>>> greeting = "It's a beautiful day in the neighbourhood."
>>> a = unicode(greeting)
>>> b = unicode(greeting)
>>> a is b
False
>>> a == b
True
Not: Burada unicode dizeleri kullanıyorum, çünkü Python bellekte yenilerini oluşturmadan normal dizeleri yeniden kullanmak için yeterince akıllı.
Burada, iki unicode dizgim var a
ve b
. Aynı içeriğe sahipler, ancak bellekteki aynı nesne değiller. Ancak, onları karşılaştırdığımızda, onların eşit karşılaştırmasını istiyoruz. Burada olan, unicode nesnesinin __eq__
yöntemi uyguladığıdır .
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
Not: __eq__
on unicode
kesinlikle bundan daha verimli bir şekilde uygulanır.
Gerekçe: İki nesnenin verileri farklıdır, ancak bazı önemli veriler aynı ise aynı nesne olarak kabul edilir. Örnek: Çoğu model verisi türü
>>> 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
Burada iki Dell monitörüm var a
ve b
. Aynı marka ve modele sahiptirler. Bununla birlikte, ne aynı verilere sahiptir ne de bellekteki aynı nesnedir. Ancak, onları karşılaştırdığımızda, onların eşit karşılaştırmasını istiyoruz. Burada olan şey, Monitor nesnesinin __eq__
yöntemi uygulamasıdır .
class Monitor(object):
# ...
def __eq__(self, other):
return self.make == other.make and self.model == other.model
Karşılaştırırken None
, daima kullanın is not
. Python'da hiçbiri bir singleton değildir - bellekte sadece bir örneği vardır.
Kimlik karşılaştırılarak , bu çok hızlı bir şekilde gerçekleştirilebilir. Python, başvurduğunuz nesnenin global None nesnesiyle aynı bellek adresine sahip olup olmadığını kontrol eder - iki sayının çok, çok hızlı bir karşılaştırması.
Eşitliği karşılaştırarak Python, nesnenizin bir __eq__
yöntemi olup olmadığını aramalıdır . Değilse, bir __eq__
yöntem arayan her bir üst sınıfı inceler . Birini bulursa, Python onu arar. Bu, özellikle __eq__
yöntem yavaşsa ve diğer nesnenin olduğunu fark ettiğinde hemen geri dönmezse kötüdür None
.
Uygulamadınız __eq__
mı? Daha sonra Python muhtemelen __eq__
yöntemi bulacaktır object
ve bunun yerine kullanacaktır - ki bu zaten nesne kimliğini kontrol eder.
Python'daki diğer birçok şeyi karşılaştırırken, kullanacaksınız !=
.
Aşağıdakileri göz önünde bulundur:
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
tek bir nesnedir, bu nedenle kimlik karşılaştırması her zaman işe yarayacaktır, oysa bir nesne eşitlik karşılaştırmasını taklit edebilir .__eq__()
.
None
, ancak None
diğer türlere karşı eşitliğin uygulanmasının bir yan etkisi olarak yanlış davranışlar ortaya çıkabilir. Sadece doğruluk sonuçları olduğu için çok fazla güvenlik etkisi değil.
>>> () () Doğru >>> 1 1'dir Doğru >>> (1,) == (1,) Doğru >>> (1,) (1,) Yanlış >>> a = (1,) >>> b = a >>> a b'dir Doğru
Bazı nesneler tek tonludur ve bu nedenle is
onlarla eşdeğerdir ==
. Çoğu değil.
()
ve 1
doğal olarak tekil değildir.
-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) ve boş küpe olan singletons. Aslında belgelenmemiş ve garanti edilmemiştir, ancak değişmesi olası değildir.