Özet: Bu bir tesadüf değil; Python'un varsayılan CPython uygulamasında _PyHASH_INF314159 olarak sabit kodlanmıştır ve 2000'de Tim Peters tarafından rasgele bir değer (açıkça π rakamlarından) seçilmiştir .
Değeri, hash(float('inf'))sayısal türler için yerleşik karma işlevinin sisteme bağlı parametrelerinden biridir ve Python 3'teki gibi de kullanılabilirsys.hash_info.inf :
>>> import sys
>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003, algorithm='siphash24', hash_bits=64, seed_bits=128, cutoff=0)
>>> sys.hash_info.inf
314159
( PyPy ile de aynı sonuçlar .)
Kod açısından, hashyerleşik bir işlevdir. Olan işaretçi tarafından verilen fonksiyon bir Python şamandıra nesne üzerinde çağırmaktadır çağrı tp_hashöznitelik dahili salınım türünde (arasında PyTypeObject PyFloat_Type), birfloat_hash işlev, tanımlandığı şekilde return _Py_HashDouble(v->ob_fval)da, var
if (Py_IS_INFINITY(v))
return v > 0 ? _PyHASH_INF : -_PyHASH_INF;
burada _PyHASH_INFolduğu gibi tanımlanmıştır 314159:
#define _PyHASH_INF 314159
Tarih açısından, 314159bu bağlamda ilk kez Python kodunda (bunu git bisectveya ile bulabilirsiniz git log -S 314159 -p) Ağustos 2000'de Tim Peters tarafından , git deposunda 39dce293 taahhüt edilene eklenmiştircpython .
Taahhüt mesajı şunu söylüyor:
Http://sourceforge.net/bugs/?func=detailbug&bug_id=111866&group_id=5470 için düzeltme . Bu yanıltıcı bir hataydı - gerçek "hata" bir sonsuzluk hash(x)olduğunda bir hata dönüş verdi oldu x. Bunu düzelttim. Alanına yeni Py_IS_INFINITYmakro
eklendi pyport.h. Float ve karmaşık sayıların karma işlemlerinde artan çoğalmayı azaltmak için kodu yeniden düzenleyerek Trent'in önceki bıçağını mantıklı bir sonuca itti. Bir hata olmasa bile şamandıraların karmaının -1'e dönebileceği son derece nadir bir hata düzeltildi (bir test vakası oluşturmaya çalışırken zaman kaybetmedim, olabileceği koddan açıkça anlaşıldı ). Geliştirilmiş karmaşık karma
artık hash(complex(x, y))sistematik olarak eşit hash(complex(y, x))değil.
Özellikle, bu o kodunu yırtık işlemek static long float_hash(PyFloatObject *v)içinde Objects/floatobject.cve sadece yapılan return _Py_HashDouble(v->ob_fval);ve tanımında long _Py_HashDouble(double v)içinde Objects/object.co satırları ekledi:
if (Py_IS_INFINITY(intpart))
/* can't convert to long int -- arbitrary */
v = v < 0 ? -271828.0 : 314159.0;
Daha önce de belirtildiği gibi, keyfi bir seçimdi. 271.828 ilk birkaç ondalık hane oluştuğunu ileri Not e .
İlgili daha sonraki taahhütler:
hash(float('nan'))olması0.