为什么0℃; ()评估为True在Python? [英] Why does 0 < () evaluate to True in Python?

查看:121
本文介绍了为什么0℃; ()评估为True在Python?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无意中输入 time.clock≤()使用Python 2.7间preTER响应之中:。下面code莫能行为:

 >>>再版(time.clock)
'<内置时钟功能和GT;'
>>> time.clock≤()
真正

此外:

 >>>进口SYS
>>>所有的sys.maxint< ()
真正>>>图(拉姆达_:0℃; _,(()[] {}))
[真,真,真]

相反:

 >>> 1<集(())
类型错误:只能与一组

问:此外,为什么,有没有空列表,元组的实际意义或目的或字典评估仿佛比任何数字?

更大

更新


  • 的人士指出,内存地址默认情况下比较:

    >>>地图(拉姆达_ :( ID(0),'<',ID(_)),(()[] {}集合([])))

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


尽管看似顺序,这是不正确



  • 的Martijn Pieters的的指出:


  

如果没有明确定义比较运算,Python 2里比较了
  数字和类型,名称,以及具有最低precedence号码。


这并不暗示什么正在调用的确切的内部方法。又见这是很有帮助的,但<一个href=\"http://stackoverflow.com/questions/18387938/how-do-python-comparison-operators-and-work-with-a-function-name-as-an-opera?lq=1\">inconclusive SO线程:

在一个IPython的2.7.5 REPL

 &GT;&GT;&GT;型(类型(()).__ name__)
出[15]:STR&GT;&GT;&GT;型(())≤; 10
出[8]:假
&GT;&GT;&GT; 10 LT;类型(())
出[11]:真
#as描述
&GT;&GT;&GT;型(())≤;类型(())
出[9]:假
&GT;&GT;&GT;型(())==型(())
出[10]:真然而:
&GT;&GT;&GT; somestr .__乐__(10)
出[20]:NotImplemented
&GT;&GT;&GT; somestr .__ LT __(10)
出[21]:NotImplemented&GT;&GT;&GT; INT .__ gt__
出[25]:&lt;方法,包装在0x1E221000&GT类型的对象'__gt__';
&GT;&GT;&GT; INT .__ lt__
出[26]:&lt;方法,包装在0x1E221000&GT类型的对象'__lt__';&GT;&GT;&GT; INT .__ LT __(无)
出[27]:NotImplemented
    #.....型(...),目录(...),类型,DIR ......
#An'诠释'实例没有一个&LT;运营商定义的
&GT;&GT;&GT; 0 .__ lt__
出[28]:AttributeError的:'诠释'对象有没有属性'__lt__#int实际上是布尔的一个子类
&GT;&GT;&GT; INT .__子类__()
输出:[BOOL]
#str作为后备类型默认的比较
&GT;&GT;&GT;类型(''.__ subclasshook__)
出[72]:builtin_function_or_method
&GT;&GT;&GT; DIR(''.__ subclasshook__)
出[73]:
['__呼叫__',
 '__类__',
 __cmp__',
 __delattr__',
 '__doc__',
 __eq__',
 '__格式__',
 __ge__',
 __getattribute__',
 __gt__',
 __hash__',
 '__在里面__',
 __le__',
 __lt__',
 __module__',
 '__名称__',
 __ne__',
 '__新__',
 '__减少__',
 __reduce_ex__',
 __repr__',
 '__自__',
 __setattr__',
 __sizeof__',
 __str__',
 __subclasshook__']
#IPython是继承STR
&GT;&GT;&GT;海峡.__子类__()
出[84]:[IPython.utils.text.LSString]


解决方案

在Python 2中,进行比较时的不同的的类型,蟒蛇排序一切之前数值类型之间,以及其余的排序类型的按类型名称

因此​​,整数排序之前的元组,但该类的实例将整理的之后的类的实例酒吧

Python 3中摒弃了这种疯狂;比较不同类型导致类型错误,而不是:

 &GT;&GT;&GT; 10 LT; ()
回溯(最近通话最后一个):
  文件&LT;&标准输入GT;,1号线,上述&lt;&模块GT;
类型错误:unorderable类型:INT()&LT;元组()

Python的设置()类型已超载&GT;通过实施的运营商HTTP ://docs.python.org/2/reference/datamodel.html#object.__gt__相对=nofollow> __ __ GT 或'大于'魔术方法;它被称为为 1 LT;集()前pression因为 INT 类型没有 __ LT __ ,低 - 那么和Python测试在这种情况下,逆;毕竟, X&LT;是为真,如果 Y'GT; X 是真实的。

设置.__ GT __()勾引起了当其它操作数不是<$ C $ 类型错误 C>设置

 &GT;&GT;&GT; 1 .__ LT __(集())
回溯(最近通话最后一个):
  文件&LT;&标准输入GT;,1号线,上述&lt;&模块GT;
AttributeError的:'诠释'对象有没有属性'__lt__
&GT;&GT;&GT;集().__ GT __(1)
回溯(最近通话最后一个):
  文件&LT;&标准输入GT;,1号线,上述&lt;&模块GT;
类型错误:只能与一组

重载&GT; (大于)运算符台用于测试,如果左边操作数是一个的右手操作的超集。 (从技术上说,设置对象实现C-API的 PyTypeObject.tp_richcompare 功能,而不是 __ __ GT 直接挂钩,但在 __ __ GT 挂钩转化为在这种情况下自动)。

tp_richcompare 通话

当一个重载的比较方法( 之一.__ LT __() .__乐__() .__ EQ __()。__ne __()。__gt __()。__ge __()。__cmp __() )返回 NotImplemented 单独的对象这预示着,比较不支持和Python回落到默认的行为。此默认行为,在如前所述怎么办Python的比较操作符&LT;和大于与函数的名称作为操作数工作?Python的2和3之间不同。

对于Python 3,比较钩回 NotImplemented 导致Python来筹集类型错误

 &GT;&GT;&GT;类Foo():
... DEF __lt __(自我,其他):返回NotImplemented
...
&GT;&GT;&GT;美孚()&LT;美孚()
回溯(最近通话最后一个):
  文件&LT;&标准输入GT;,1号线,上述&lt;&模块GT;
类型错误:unorderable类型:富()&LT;美孚()

Python 2中是较顽固,当返回或没有挂钩已经实施 NotImplemented 中,C code在的 default_3way_compare() C函数 ,其中:


  • 将内存地址时,订单类型两个对象是相同的(行768-776)

  • 订单任何东西之前(线780-783)

  • 其他类型的( PyNumber_Check 测试设置类型名称为空,行786-793)之前
  • 订单号码
  • 按类型名称订单( V-&GT; ob_type-&GT; tp_name W-&GT; ob_type-&GT; tp_name 中的行786-793)

  • 如果类型的名称的是相同的,由类型对象的内存地址(线800和801)。
  • 订单

I inadvertently typed time.clock<() with the Python 2.7 interpreter response being: 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?


Update:

  • Viktor pointed out that memory-addresses are compared by default:

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

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

Despite the seeming order, this is incorrect.


  • Martijn Pieters points out that:

Without an explicit comparison operator defined, Python 2 compares by Numbers and Type-names, with numbers having the lowest precedence.

This does not hint at what exact internal methods are being invoked. See also this helpful but inconclusive SO thread:

In an 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.

Thus, integers sort before tuples, but instances of class Foo will sort after instances of class Bar.

Python 3 does away with this madness; comparing different types results in a TypeError instead:

>>> 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; 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; after all, x < y is true if y > x is true.

The set.__gt__() hook raises a TypeError when the other operand is not a 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

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. (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).

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. This default behaviour, as already stated in How do Python comparison operators < and > work with a function name as an operand? differs between Python 2 and 3.

For Python 3, a comparison hook returning NotImplemented causes Python to raise 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:

  • Orders by memory addresses when the types of both objects are the same (line 768-776)
  • Orders None before anything (line 780-783)
  • Orders numbers before other types (PyNumber_Check tests set type name to empty, lines 786-793)
  • Orders by typename (v->ob_type->tp_name and w->ob_type->tp_name in lines 786-793)
  • If the type names are the same, orders by memory address of the type objects (lines 800 and 801).

这篇关于为什么0℃; ()评估为True在Python?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆