resoult在python啥意思,python - __lt__而不是__cmp__
python - __lt__而不是__cmp__
Python 2.x有兩種方法可以重載比較運算符,__cmp__或者#34;豐富的比較運算符" 例如__cmp__。據說富裕的比較超載是首選,但為什么會這樣呢?
豐富的比較運算符更容易實現每個,但您必須使用幾乎相同的邏輯實現其中幾個。 但是,如果你可以使用內置的__cmp__和元組排序,那么<=變得非常簡單并完成所有的比較:
class A(object):
def __init__(self, name, age, other):
self.name = name
self.age = age
self.other = other
def __cmp__(self, other):
assert isinstance(other, A) # assumption for this example
return cmp((self.name, self.age, self.other),
(other.name, other.age, other.other))
這種簡單性似乎比重載所有6(!)豐富的比較更好地滿足了我的需求。 (但是,如果依靠&#34;交換的參數&#34; /反映的行為,你可以把它歸結為&#34; 4,但這導致并發癥的凈增加,在我的拙見中。)
如果我只是超載__cmp__,是否有任何不可預見的陷阱需要注意?
我理解__cmp__,<=,==等操作符可以為其他目的而重載,并且可以返回他們喜歡的任何對象。 我并不是在詢問這種方法的優點,而是僅僅考慮使用這些算子進行比較時的差異,這與他們對數字的意義相同。
更新:正如克里斯托弗指出的那樣,__cmp__正在消失3.x. 是否有任何替代方案可以使實施比較像上面的__cmp__一樣簡單?
5個解決方案
84 votes
是的,很容易實現所有內容,例如: __key__有一個mixin類(或者一個元類,或者一個類裝飾器,如果你的味道以這種方式運行)。
例如:
class ComparableMixin:
def __eq__(self, other):
return not self
def __ne__(self, other):
return self
def __gt__(self, other):
return other
def __ge__(self, other):
return not self
def __le__(self, other):
return not other
現在你的類只能定義__key__并從ComparableMixin中多次繼承(在需要其他任何基礎之后,如果有的話)。 類裝飾器非常相似,只是插入類似的函數作為它所裝飾的新類的屬性(結果可能在運行時在顯微鏡下更快,在內存方面同樣是微小的成本)。
當然,如果你的班級有一些特別快速的實施方式(例如)__key__和__cmp__,它應該直接定義它們以便不使用mixin的版本(例如,__lt__的情況) - 在 事實__ne__可能被定義為促進這一點:
def __ne__(self, other):
return not self == other
但在上面的代碼中,我想保持令人愉悅的對稱性,只使用__key__ ;-)。至于為什么__cmp__必須去,因為我們確實有__lt__和朋友,為什么要保持另一種不同的方式來做同樣的事情呢? 它在每個Python運行時(Classic,Jython,IronPython,PyPy,......)中都非常重要。 肯定不會有錯誤的代碼就是那些不存在的代碼 - 而Python的原則應該是理想情況下執行任務的一種明顯方式(C具有相同的原則) &#34; ISO標準的C&#34;部分,btw)。
這并不意味著我們會竭盡全力禁止某些事情(例如,某些用途的mixins和類裝飾器之間的近似等價),但這肯定意味著我們不想隨身攜帶代碼 冗余存在的編譯器和/或運行時只是為了支持多個等效方法來執行完全相同的任務。
進一步編輯:實際上有一種更好的方法可以為許多類提供比較和散列,包括問題中的方法 - 一種__key__方法,正如我在對問題的評論中提到的那樣。 因為我從來沒有為它編寫PEP,所以如果你喜歡的話,你現在必須使用Mixin(&amp; c)來實現它:
class KeyedMixin:
def __lt__(self, other):
return self.__key__() < other.__key__()
# and so on for other comparators, as above, plus:
def __hash__(self):
return hash(self.__key__())
對于實例與其他實例的比較來說,將每個元組的元組與幾個字段進行比較,這是一個非常常見的情況 - 然后,散列應該在完全相同的基礎上實現。 __key__特殊方法直接解決了這個問題。
Alex Martelli answered 2019-08-14T04:12:29Z
44 votes
為了簡化這種情況,Python 2.7 + / 3.2 +中的類裝飾器,functools.total_ordering,可用于實現Alex建議的內容。 來自文檔的示例:
@total_ordering
class Student:
def __eq__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) ==
(other.lastname.lower(), other.firstname.lower()))
def __lt__(self, other):
return ((self.lastname.lower(), self.firstname.lower()) <
(other.lastname.lower(), other.firstname.lower()))
jmagnusson answered 2019-08-14T04:12:55Z
9 votes
這由PEP 207 - Rich Comparisons涵蓋
此外,__cmp__在python 3.0中消失了。 (請注意,它不在[http://docs.python.org/3.0/reference/datamodel.html]上,但它位于[http://docs.python.org/2.7/reference/datamodel.html])
Christopher answered 2019-08-14T04:13:29Z
0 votes
靈感來自Alex Martelli的ComparableMixin&amp; KeyedMixin答案,我想出了以下mixin。它允許您實現單個_compare_to()方法,該方法使用基于密鑰的比較類似于KeyedMixin,但允許您的類根據other的類型選擇最有效的比較密鑰。(請注意,這個mixin對于可以測試相等而不是順序的對象沒有多大幫助)。
class ComparableMixin(object):
"""mixin which implements rich comparison operators in terms of a single _compare_to() helper"""
def _compare_to(self, other):
"""return keys to compare self to other.
if self and other are comparable, this function
should return ``(self key, other key)``.
if they aren't, it should return ``None`` instead.
"""
raise NotImplementedError("_compare_to() must be implemented by subclass")
def __eq__(self, other):
keys = self._compare_to(other)
return keys[0] == keys[1] if keys else NotImplemented
def __ne__(self, other):
return not self == other
def __lt__(self, other):
keys = self._compare_to(other)
return keys[0] < keys[1] if keys else NotImplemented
def __le__(self, other):
keys = self._compare_to(other)
return keys[0] <= keys[1] if keys else NotImplemented
def __gt__(self, other):
keys = self._compare_to(other)
return keys[0] > keys[1] if keys else NotImplemented
def __ge__(self, other):
keys = self._compare_to(other)
return keys[0] >= keys[1] if keys else NotImplemented
Eli Collins answered 2019-08-14T04:13:58Z
0 votes
(17/17/17編輯,以考慮評論。)
我在上面嘗試了類似的mixin答案。 我和#34;無&#34;遇到了麻煩。 這是一個修改版本,處理與&#34;無&#34;的相等比較。 (我沒有理由因為缺乏語義而無法與None進行不等式比較):
class ComparableMixin(object):
def __eq__(self, other):
if not isinstance(other, type(self)):
return NotImplemented
else:
return not self
def __ne__(self, other):
return not __eq__(self, other)
def __gt__(self, other):
if not isinstance(other, type(self)):
return NotImplemented
else:
return other
def __ge__(self, other):
if not isinstance(other, type(self)):
return NotImplemented
else:
return not self
def __le__(self, other):
if not isinstance(other, type(self)):
return NotImplemented
else:
return not other
Gabriel Ferrer answered 2019-08-14T04:14:32Z
總結
以上是生活随笔為你收集整理的resoult在python啥意思,python - __lt__而不是__cmp__的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php压制错误的代码,为什么要压制PHP
- 下一篇: php安卓交互安全,php结合安卓客户端