2013-03-18 47 views
5

雖然標題可以解釋爲三個問題,但實際問題很容易描述。在Linux系統上,我安裝了python 2.7.3,並且想要警告python 3不兼容。因此,我的代碼片段(tester.py)看起來像:如何消除相等運算符的python3棄用警告?

#!/usr/bin/python -3 

class MyClass(object):  
    def __eq__(self, other): 
     return False 

當我執行這個代碼片斷(被認爲是隻顯示問題,而不是實際的代碼,我用我的項目)作爲

./tester.py 

我得到以下棄用警告:

./tester.py:3: DeprecationWarning: Overriding __eq__ blocks inheritance of __hash__ in 3.x 
    class MyClass(object): 

我的問題:如何更改此代碼段擺脫了警告,即以使其兼容版本3?我想以正確的方式實現相等運算符,而不僅僅是壓制警告或類似的東西。

+0

'__eq__'將返回false從'object'繼承的對象,除非'A爲A' – thkang 2013-03-18 07:39:53

回答

5

documentation頁用於Python 3.4:

如果一個類沒有定義__eq__()方法不應該限定__hash__()操作要麼;如果它定義了__eq__()而不是__hash__(),則其實例將不可用作可哈希集合中的項目。如果一個類定義了可變對象並實現了一個__eq__()方法,那麼它不應該實現__hash__(),因爲可哈希集合的實現要求密鑰的哈希值是不可變的(如果對象的哈希值更改,它將位於錯誤的哈希桶中)。

基本上,您需要定義一個__hash()__函數。

問題是,對於用戶定義的類,__eq()____hash()__函數是自動定義的。

x.__hash__()返回一個適當的值,使得x == y意味着 既該x is yhash(x) == hash(y)

如果您只定義了__eq()__,那麼__hash()__設置爲返回None。所以你會撞到牆上。

如果您不想爲執行__hash()__而煩惱,並且您確定您的對象永遠不會被散列,您只需明確聲明__hash__ = None負責警告即可。

+0

只是一個虛擬的散列函數基本返回nonesense?或者一個真正返回可用散列值的函數?但是,我需要這樣做,從文檔片段中不清楚。 – Alex 2013-03-18 07:11:07

+0

同樣,從同一頁面:'__hash __()'應該返回一個整數。唯一需要的屬性是比較相等的對象具有相同的散列值 – 2013-03-18 07:13:39

+0

閱讀關於散列和eq函數的描述 - 它們表示清楚。 – 2013-03-18 07:14:25

0

亞歷克斯:python的-3選項警告你一個潛在的問題;它不知道你沒有在集合中使用MyClass的實例或在映射中作爲鍵,所以它警告說,如果你是的話,你可能依賴的東西是行不通的。如果您不以這種方式使用MyClass,請忽略該警告。這是一個愚蠢的工具來幫助你捕捉潛在的問題;最後,你需要具備真正的情報來確定哪些警告真的很重要。

如果你真的關心抑制警告 - 或者更確切地說,如果一個類是可變的,你想確保它是成套或在任何映射按鍵使用不 - 簡單賦值__hash__ = None(正如Sudipta指出的那樣)在班級體內應該爲你做。由於None不可調用,這使得實例不可哈希。

class MyClass (object): 
     def __eq__(self, other): return self is other 
     __hash__ = None