2017-06-27 99 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