2017-06-27 76 views
0

所以在Python 3中,我可以使用object().__eq__。我目前使用它作爲可映射函數,相當於lambda x: x is object()Python 2 vs Python 3雙下劃線方法

我正在使用它作爲定點(因爲None將有不同的含義從沒有參數)。

>>> import sys 
>>> print(sys.version) 
3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 18:41:36) [MSC v.1900 64 bit (AMD64)] 
>>> object.__eq__ 
<slot wrapper '__eq__' of 'object' objects> 
>>> object().__eq__ 
<method-wrapper '__eq__' of object object at 0x000002CC4E569120> 

但是在Python 2,這不起作用:

>>> import sys 
>>> print sys.version 
2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] 
>>> object.__eq__ 
<method-wrapper '__eq__' of type object at 0x0000000054AA35C0> 
>>> object().__eq__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'object' object has no attribute '__eq__' 
>>> dir(object) 
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 

爲什麼沒有這個功能存在?我怎麼能效仿(performantly與Python 2兼容)

$ python3 -m timeit "sentinel = object(); tests = [sentinel] * 100 + [None] * 100" "list(filter(sentinel.__eq__, tests))" 
100000 loops, best of 3: 8.8 usec per loop 
$ python3 -m timeit "sentinel = object(); tests = [sentinel] * 100 + [None] * 100; exec('def is_sentinel(x): return sentinel is x', locals(), globals())" "list(filter(is_sentinel, tests))" 
10000 loops, best of 3: 29.1 usec per loop 
+0

這正是您不應該使用像這樣的'__dunder__'方法的原因。使用'import operator; operator.eq' –

+0

或者實際上使用'lambda thing:thing is sentinel';平等並不一定是身份。 – jonrsharpe

+0

@jonrsharpe我使用字面上的s = object()'。爲此,我認爲平等被定義爲身份。 – Artyer

回答

3

如果你想有一個函數來測試針對一個固定對象的平等,這是

from functools import partial 
from operator import eq 

equals_thing = partial(eq, thing) # instead of thing.__eq__ 

這將表現略有不同從thing.__eq__,因爲它也提供了另一個參數來提供比較,並且它不會返回NotImplemented

如果你想要一個身份測試無論什麼時候,用operator.is_代替operator.eq

from operator import is_ 

is_thing = partial(is_, thing) 

如果你真的想要一個原__eq__電話,NotImplemented和所有的Python 3的行爲,那麼根據類型,你可能不得不手動重新實現它。對於object,那會是

lambda x: True if x is thing else NotImplemented 

在Python 2,並不是每一個對象定義__eq__,而事實上,並不是每一個對象定義任何形式的平等的比較可言,甚至舊式__cmp__==的身份比較回退發生在任何對象的方法之外。

+0

我不知道'operator.is_'。謝謝!當它讓我時,我會接受。 – Artyer