Bu, __dunder__eşdeğer operatörleri için çoğu zaman uygun ikame olmadıklarından , yöntemlerin doğrudan kullanılmaması gerektiğine dair harika bir örnektir ; ==Bunun yerine operatörü eşitlik karşılaştırmaları için kullanmalısınız veya bu özel durumda, kontrol ederken Nonekullanın is(daha fazla bilgi için yanıtın altına atlayın).
Yaptığın
None.__eq__('a')
Karşılaştırılan NotImplementedtürler farklı olduğu için hangi geri dönüşler . Farklı türde iki nesne gibi, bu şekilde karşılaştırılan bir örneği ele alalım 1ve 'a'. Yapmak (1).__eq__('a')da doğru değil ve geri dönecek NotImplemented. Eşitlik için bu iki değeri karşılaştırmanın doğru yolu,
1 == 'a'
Burada ne olur
- İlk önce
(1).__eq__('a')denenir, hangi geri döner NotImplemented. Bu, işlemin desteklenmediğini gösterir.
'a'.__eq__(1)çağrılır, bu da aynı şeyi döndürür NotImplemented. Yani,
- Nesneler aynı değilmiş gibi ele alınır ve
Falseiade edilir.
İşte bunun nasıl gerçekleştiğini göstermek için bazı özel sınıfları kullanan küçük bir MCVE:
class A:
def __eq__(self, other):
print('A.__eq__')
return NotImplemented
class B:
def __eq__(self, other):
print('B.__eq__')
return NotImplemented
class C:
def __eq__(self, other):
print('C.__eq__')
return True
a = A()
b = B()
c = C()
print(a == b)
print(a == c)
print(c == a)
Elbette bu , operasyonun neden doğru döndüğünü açıklamıyor . Bunun nedeni NotImplemented, aslında doğru bir değer olmasıdır:
bool(None.__eq__("a"))
İle aynı,
bool(NotImplemented)
Değerleri truthy kabul edilir ve falsy ne hakkında daha fazla bilgi için, dokümanlar bölümüne bakın Hakikat Değer Testi , hem de bu cevabı . Burada bunun NotImplementeddoğru olduğunu belirtmekte fayda var , ancak sınıf geri dönen bir __bool__veya __len__yöntemi Falseveya 0sırasıyla tanımlamış olsaydı farklı bir hikaye olurdu .
==Operatörün işlevsel eşdeğerini istiyorsanız , şunu kullanın operator.eq:
import operator
operator.eq(1, 'a')
Ancak, daha önce de belirtildiği gibi, kontrol ettiğiniz bu özel senaryo için şunu Nonekullanın is:
var = 'a'
var is None
var2 = None
var2 is None
Bunun işlevsel eşdeğeri kullanmaktır operator.is_:
operator.is_(var2, None)
Noneözel bir nesnedir ve herhangi bir zamanda bellekte yalnızca 1 sürüm bulunur. IOW, NoneTypesınıfın yegane singletonudur (ancak aynı nesnenin herhangi bir sayıda referansı olabilir). PEP8 kurallar bu açık hale getirmektedir:
Tekillerle karşılaştırmalar Noneher zaman eşitlik operatörleriyle isveya
is notasla eşitlik operatörleriyle yapılmalıdır .
Özetle, singletonların gibi için None, bir referans kontrolü isdaha uygundur, hem olsa ==ve issadece iyi çalışacaktır.