Why does 0 <() evaluate to True in Python?

I inadvertently typed time.clock<()the answer to the Python interpreter 2.7: True. The following example illustrates the behavior:

>>> repr(time.clock)
'<built-in function clock>'
>>> time.clock<()
True

Wherein:

>>> import sys
>>> sys.maxint < ()
True

>>> map(lambda _:0<_,((),[],{}))
[True, True, True]

On the contrary:

>>> 1<set(())
TypeError: can only compare to a set

Question: In addition, why is there a practical meaning or purpose for empty evaluations list, tupleor dictas if they were more than any number?


Update :

  • Victor noted that memory addresses are compared by default:

    >>> map(lambda _:(id(0),'<',id(_)),((),[],{}, set([])))

    [(31185488L, '<', 30769224L), (31185488L, '<', 277144584L), (31185488L, '<', 279477880L), (31185488L, '<', 278789256L)]

Despite the apparent order, this is not true .


  • Martijn Pieters indicates that:

Without an explicit comparison operator, Python 2 is compared by Numbers and type names with numbers with the lowest priority.

, . . , SO:

IPython 2.7.5 REPL

>>> type(type(()).__name__)
Out[15]: str

>>> type(()) < 10
Out[8]: False
>>> 10 < type(())
Out[11]: True
#as described
>>> type(()) < type(())
Out[9]: False
>>> type(()) == type(())
Out[10]: True

However:
>>> 'somestr' .__le__(10)
Out[20]: NotImplemented
>>> 'somestr' .__lt__(10)
Out[21]: NotImplemented

>>> int.__gt__
Out[25]: <method-wrapper '__gt__' of type object at 0x1E221000>
>>> int.__lt__
Out[26]: <method-wrapper '__lt__' of type object at 0x1E221000>

>>> int.__lt__(None)
Out[27]: NotImplemented
    #.....type(...), dir(...), type, dir......
#An 'int' instance does not have an < operator defined
>>> 0 .__lt__
Out[28]: AttributeError: 'int' object has no attribute '__lt__'

#int is actually a subclass of bool
>>>int.__subclasses__()
Out: [bool]
#str as the fallback type for default comparisons
>>> type(''.__subclasshook__)
Out[72]: builtin_function_or_method
>>> dir(''.__subclasshook__)
Out[73]: 
['__call__',
 '__class__',
 '__cmp__',
 '__delattr__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__lt__',
 '__module__',
 '__name__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__self__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__']
#IPython is subclassing 'str' 
>>> str.__subclasses__()
Out[84]: [IPython.utils.text.LSString]
0
1

Python 2 , .

, , Foo Bar.

3 ; TypeError:

>>> 10 < ()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < tuple()

Python set() >, __gt__ ""; 1 < set(), int __lt__, - Python ; , x < y , y > x .

set.__gt__() TypeError, set:

>>> 1 .__lt__(set())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__lt__'
>>> set().__gt__(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only compare to a set

> () , . (, set C-API PyTypeObject.tp_richcompare, __gt__ hook, __gt__ hook tp_richcompare ).

( .__lt__(), .__le__(), .__eq__(), . __ne__(), . __gt__(), . __ge__(), . __cmp__()) NotImplemented singleton, , , Python . , Python < > ? Python 2 3.

Python 3, NotImplemented, Python TypeError:

>>> class Foo():
...     def __lt__(self, other): return NotImplemented
... 
>>> Foo() < Foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Foo() < Foo()

Python 2 , NotImplemented , C default_3way_compare() C function, :

  • , ( 768-776)
  • None - ( 780-783)
  • (PyNumber_Check , 786-793)
  • typename (v->ob_type->tp_name w->ob_type->tp_name 786-793)
  • , ( 800 801).
+5

Source: https://habr.com/ru/post/1540876/


All Articles