程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python魔法方法(10):__hash__(self) 方法

編輯:Python

Python 的對象天生擁有一些神奇的方法,它們總被雙下劃線所包圍,它們是面向對象的 Python 的一切。它們是可以給你的類增加魔力的特殊方法,如果你的對象實現(重載)了某一個魔法方法,那麼這個方法就會在特殊的情況下自動被 Python 所調用。

功能

定義對象被 hash() 函數調用時的行為。

參數

self 表示對象自己。

返回值

一個整數,表示對象的哈希值。

示例

class MyTest(object):
def __init__(self):
self.name = '阿珍'
self.age = 18
def __hash__(self):
return hash(str(self))
sample = MyTest()
print(hash(sample))

python3 中,在 set,frozenset,dict 這三種數據結構中,都要求鍵值 key 是可 hash 的,因為要保證 key 的唯一性。
而__hash__實際上是返回一個 int 值,用來唯一標記這個對象。

一般講解 hash 時,同時需要使用 eq。

可哈希的集合(hashed collections),需要集合的元素實現了__eq__和__hash__,而這兩個方法可以比喻如下:
哈希集合就是很多個桶,但每個桶裡面只能放一個球。
__hash__ 函數的作用就是找到桶的位置,到底是幾號桶。
__eq__ 函數的作用就是當桶裡面已經有一個球了,但又來了一個球,它聲稱它也應該裝進這個桶裡面(__hash__函數給它說了桶的位置),雙方僵持不下,那就得用 __eq__ 函數來判斷這兩個球是不是相等的(equal),如果是判斷是相等的,那麼後來那個球就不應該放進桶裡,哈希集合維持現狀。
當可哈希集合(set,frozenset,dict)調用hash函數時,應該返回一個int值。唯一的要求就是,如果判斷兩個對象相等,那麼他們的hash值也應該相等。當比較兩個對象相等時是使用對象的成員來比較時,建議要把成員弄進元祖裡,再得到這個元祖的hash值來比較。

當class沒有定義__eq__()方法時,那麼它也不應該定義__hash__()方法。如果它定義了__eq__()方法,卻沒有定義__hash__()方法,那麼這個類的實例就不能在可哈希集合使用。如果一個類定義了一個可變對象(這裡應該是指class的成員之一為可變對象),且implement了__eq__()方法,那麼這個類就不應該implement __hash__()方法,因為可哈希對象的實現(implement )要求鍵值key的hash值是不變的(如果一個對象的hash值改變了,那麼它會被放在錯誤的hash桶裡)。

如下示例:

class Foo:
def __init__(self, item):
self.item = item
def __eq__(self, other):
print('使用了equal函數的對象的id', id(self))
if isinstance(other, self.__class__):
return self.__dict__ == other.__dict__
else:
return False
def __hash__(self):
print('f' + str(self.item) + '使用了hash函數')
return hash(self.item)
f1 = Foo(1)
f2 = Foo(2)
f3 = Foo(3)
fset = set([f1, f2, f3])
print(fset)
print()
f = Foo(3)
fset.add(f)
print('f3的id:', id(f3))
print('f的id:', id(f))


 


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved