2017-06-27 11 views
0

したがって、Python 3ではobject().__eq__を使用できます。私は現在、それをlambda x: x is object()に相当するマップ可能な関数として使用しています。Python 2と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__'] 

を?これはthing.__eq__とは若干異なる動作をします

from functools import partial 
from operator import eq 

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

そして、あなたは機能が固定されたオブジェクトに対する等価性をテストしたい場合は、私は

$ 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

または実際に 'ラムダ物事:物はセンチネル'を使用します。平等は必ずしも同一性ではありません。 – jonrsharpe

+0

@jonrsharpe私は文字通り 's = object()'を使用しています。そのために、私は平等がアイデンティティとして定義されていると思います。 – Artyer

答えて

3

(performantly Pythonの2相性で)それをエミュレートすることができますどのように、それは、ですそれはまた、比較を提供する際にもう1つの引数を与えるので、NotImplementedを返しません。あなたはどんなアイデンティティのテストをしたいない場合

operator.is_代わりのoperator.eq使用:

from operator import is_ 

is_thing = partial(is_, thing) 

あなたが実際にその後、種類に応じて、生__eq__コール、NotImplemented、すべてのPythonの3行動を望んでいた場合手動で再実装する必要があるかもしれません。 objectのために、それはPythonの2で

lambda x: True if x is thing else NotImplemented 

だろう、いないすべてのオブジェクトは、__eq__を定義し、実際には、いないすべてのオブジェクトは、すべての等価比較の任意の並べ替え、でも古いスタイル__cmp__を定義します。 ==のアイデンティティ比較フォールバックは、オブジェクトのメソッドの外部で発生します。

+0

私は 'operator.is_'について知らなかった。ありがとう!私はそれを受け入れることができます。 – Artyer

関連する問題