[英]Why does 0 < () evaluate to True in Python?
I inadvertently typed time.clock<()
with the Python 2.7 interpreter response being: True
. 我无意中输入了time.clock<()
,而Python 2.7解释器响应为: True
。 The following code exemplifies the behavior: 下面的代码举例说明了此行为:
>>> repr(time.clock)
'<built-in function clock>'
>>> time.clock<()
True
Moreover: 此外:
>>> import sys
>>> sys.maxint < ()
True
>>> map(lambda _:0<_,((),[],{}))
[True, True, True]
In contrast: 相反:
>>> 1<set(())
TypeError: can only compare to a set
Question: Besides why, is there a practical meaning or purpose of an empty list
, tuple
or dict
evaluating as if were greater than any number? 问题: 除了为什么,还有一个空list
, tuple
或dict
评估是否大于任何数字是否有实际意义或目的?
Update : 更新 :
Viktor pointed out that memory-addresses are compared by default: Viktor指出,默认情况下会比较内存地址:
>>> map(lambda _:(id(0),'<',id(_)),((),[],{}, set([])))
[(31185488L, '<', 30769224L), (31185488L, '<', 277144584L), (31185488L, '<', 279477880L), (31185488L, '<', 278789256L)]
Despite the seeming order, this is incorrect . 尽管顺序看似, 但这是不正确的 。
Without an explicit comparison operator defined, Python 2 compares by Numbers and Type-names, with numbers having the lowest precedence. 在没有定义显式比较运算符的情况下,Python 2会按数字和类型名称进行比较,数字优先级最低。
This does not hint at what exact internal methods are being invoked. 这并不暗示正在调用确切的内部方法。 See also this helpful but inconclusive SO thread : 另请参见此有用但不确定的SO线程 :
In an IPython 2.7.5 REPL 在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]
In Python 2, when comparing different types, python sorts numeric types before everything else, and between the rest sorts types by type name . 在Python 2中,当比较不同类型时,python将数字类型排在其他所有类型之前,其余之间按类型name对类型进行排序。
Thus, integers sort before tuples, but instances of class Foo
will sort after instances of class Bar
. 因此,整数在元组之前排序,但是Foo
类的实例将在 Bar
类的实例之后排序。
Python 3 does away with this madness; Python 3消除了这种疯狂; comparing different types results in a TypeError instead: 比较不同类型会导致TypeError:
>>> 10 < ()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < tuple()
The Python set()
type has overloaded the >
operator by implementing the __gt__
or 'greater then' magic method; Python set()
类型通过实现__gt__
或'greater then'魔术方法来重载>
运算符; it is called for the 1 < set()
expression because the int
type has no __lt__
, lower-then and Python tests the inverse in that case; 它被称为1 < set()
表达式,因为int
类型没有__lt__
,请lower-then,然后在这种情况下,Python将测试逆向; after all, x < y
is true if y > x
is true. 毕竟,如果y > x
为true,则x < y
为true。
The set.__gt__()
hook raises a TypeError
when the other operand is not a set
: 当另一个操作数不是set
时, set.__gt__()
挂钩引发TypeError
:
>>> 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
The overloaded >
(greater then) operator for sets is used to test if the left-hand operand is a proper superset of the right-hand operand . set的重载>
(大于)运算符用于测试左侧操作数是否是右侧操作数的适当超集 。 (Technically, set
objects implement the C-API PyTypeObject.tp_richcompare
function, not the __gt__
hook directly, but the __gt__
hook translates to a tp_richcompare
call in that case automatically). (在技术上, set
对象实现了C-API PyTypeObject.tp_richcompare
功能,而不是__gt__
钩直接,但__gt__
钩转换为一个tp_richcompare
自动在这种情况下,呼叫)。
When an overloaded comparison method (one of .__lt__()
, .__le__()
, .__eq__()
, . __ne__()
, . __gt__()
, . __ge__()
, or . __cmp__()
) returns the NotImplemented
singleton object this signals that the comparison is not supported and Python falls back to the default behaviour. 当一个重载比较方法(之一.__lt__()
.__乐__() , .__le__()
.__当量__() , .__eq__()
。__ne __() , . __ne__()
。__gt __() , . __gt__()
。__ge __() ,
或. __ge__()
。__cmp __() )
返回NotImplemented
Singleton对象此表示不支持该比较,并且Python恢复为默认行为。 This default behaviour, as already stated in How do Python comparison operators < and > work with a function name as an operand? 如Python比较运算符<和>如何将函数名称用作操作数所述,这种默认行为是? differs between Python 2 and 3. 在Python 2和3之间有所不同。
For Python 3, a comparison hook returning NotImplemented
causes Python to raise TypeError
: 对于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 is more stubborn and when NotImplemented
is returned or no hooks have been implemented, the C code ends up in the default_3way_compare()
C function , which: Python 2更顽固,当返回NotImplemented
或未实现任何钩子时,C代码最终以default_3way_compare()
C函数结尾:
None
before anything (line 780-783) None
任何命令(780-783行) PyNumber_Check
tests set type name to empty, lines 786-793) 在其他类型之前订购数字( PyNumber_Check
测试将类型名称设置为空,行786-793) v->ob_type->tp_name
and w->ob_type->tp_name
in lines 786-793) 按类型名w->ob_type->tp_name
行中的v->ob_type->tp_name
和w->ob_type->tp_name
tp_name)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.