简体   繁体   English

可以相互比较的内置Python 3类型是什么?

[英]What are built-in Python 3 types that can be compared to each other?

In Python 2, it was possible to compare objects of different types such as int to str by having an implicit comparison of the text string of types (that is, in lexicographic order, string 'int' is less than string 'str' and string 'list' is less than string 'tuple' ). 在Python 2中,可以通过对类型的文本字符串进行隐式比较来比较不同类型的对象(如intstr (即,按字典顺序,字符串'int'小于字符串'str'和string 'list'小于字符串'tuple' )。

Hence, in Python 2, 5 < 'hello' returns True . 因此,在Python 2中, 5 < 'hello'返回True One can read more about why this was allowed in answer to Why is ''>0 True in Python? 人们可以阅读为什么在Python中为什么''> 0 True''来了解为什么允许这样做 .

In Python 3, this raises builtins.TypeError: unorderable types: int() < str() exception. 在Python 3中,这引发了builtins.TypeError: unorderable types: int() < str()异常。

This web page says 这个网页

The strict approach to comparing in Python 3 makes it generally impossible to compare different types of objects. 在Python 3中严格的比较方法通常使比较不同类型的对象成为不可能。

Does it mean there are some built-in types or special cases where it would be possible for any built-in types to be compared without causing TypeError ? 这是否意味着存在某些内置类型或特殊情况,可以在不引起TypeError情况下比较任何内置类型? I am not talking about custom types where the necessary dunder methods are implemented to properly support comparison. 我不是在谈论自定义类型,在其中实现必要的dunder方法以正确地支持比较。

All these are valid statements (and they all evaluate to True ): 所有这些都是有效的语句(它们的所有结果都为True ):

0 < True
0 < 1.
0. < True
{0} < frozenset((0, 1))

The only thing that may look odd here is that 0. == False and 1. == True . 唯一看起来奇怪的是0. == False1. == True

On the other hand, you can still reproduce what python 2 does by casting your value to an str before comparing it (this also evaluate to True ): 另一方面,在比较之前,您仍然可以通过将值强制转换为str来重现python 2的功能(这也将True ):

str(5) < 'hello'

If you really need this behaviour you can always have a function that will cast/compare. 如果您确实需要此行为,则始终可以使用将进行转换/比较的函数。 That way you'll guarantee that objects of different types will always compare the same way, which seems to be the only constraint in python 2. 这样,您将保证不同类型的对象将始终以相同的方式进行比较,这似乎是python 2中的唯一约束。

def lt(a, b):
    return str(a) < str(b)

Or maybe even better, you can cast only when needed: 甚至更好,您只能在需要时进行投射:

def lt(a, b):
  try: 
    return a < b
  except TypeError: 
    return str(a) < str(b)

On the other hand, as suggested in the comments, in CPython's implementation, it seems like comparison is done in the following way: 另一方面,如注释中所建议,在CPython的实现中,似乎可以通过以下方式进行比较:

def lt(a, b):
  try: 
    return a < b
  except TypeError: 
    if a is None:
      return True
    if b is None: 
      return False
    if isinstance(a, numbers.Number):
      return True
    if isinstance(b, numbers.Number):
      return False
    return str(type(a)) < str(type(b))

I had already looked this up on the web before, and it appears they are indeed unsortable in Python 3, apart from the few special cases mentionned above. 我之前已经在网上进行过查找,除了上面提到的一些特殊情况外,它们似乎在Python 3中确实无法分类。

The change usually manifests itself in sorting lists: in Python 3, lists with items of different types are generally not sortable. 更改通常在排序列表中体现出来:在Python 3中,带有不同类型项的列表通常不可排序。 If you need to sort heterogeneous lists, or compare different types of objects, implement a key function to fully describe how disparate types should be ordered. 如果您需要对异构列表进行排序,或者比较不同类型的对象,请实现一个关键功能以完整描述应如何对不同类型进行排序。
Source 资源

I don't know why, but some found ways to reproduce the behavior of Python 2 using Python 3. 我不知道为什么,但是有些人找到了使用Python 3重现Python 2行为的方法。

Maybe you should take a look at this or that . 也许您应该看看这个那个 This question also highlighted the change in 2011: 这个问题也突出了2011年的变化:

Found it: Buried in PEP 3100: "Comparisons other than == and != between disparate types will raise an exception unless explicitly supported by the type" 发现它:埋在PEP 3100中:“除非类型明确支持,否则不同类型之间的==和!=以外的比较将引发异常”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM