So in Python 3 kann ich object().__eq__
verwenden. Ich verwende es derzeit als eine mappable Funktion, die lambda x: x is object()
entspricht.Python 2 vs Python 3 doppelte Unterstreichungsmethoden
Ich benutze es als Sentinel (als None
hätte eine andere Bedeutung als kein Argument).
>>> 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>
Aber in Python 2, das nicht funktioniert:
>>> 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__']
Warum nicht existiert diese Funktion? Und wie kann ich es emulieren (performant mit Python 2 Kompatibilität)
$ 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
Das ist genau der Grund, warum Sie '__dunder__' Methoden wie diese nicht verwenden sollten. Verwenden Sie 'Import-Operator; operator.eq' –
Oder verwenden Sie eigentlich 'Lambda-Ding: Ding ist Sentinel'; Gleichheit ist nicht notwendigerweise Identität. – jonrsharpe
@jonrsharpe Ich benutze buchstäblich 's = object()'. Dafür denke ich, dass Gleichheit als Identität definiert ist. – Artyer