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

问题描述 投票:1回答:2

在Python 2中,有可能通过隐式比较类型的文本字符串(即,按字典顺序排列,字符串int小于字符串str和字符串'int'小于)来比较不同类型的对象,如'str''list'。 string 'tuple')。

因此,在Python 2中,5 < 'hello'返回True。人们可以阅读更多关于为什么允许回答Why is ''>0 True in Python?的原因。

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

web page

在Python 3中进行比较的严格方法使得通常无法比较不同类型的对象。

这是否意味着有一些内置类型或特殊情况可以比较任何内置类型而不会导致TypeError?我不是在谈论自定义类型,其中实现了必要的dunder方法以正确支持比较。

python python-3.x comparison operators typing
2个回答
1
投票

所有这些都是有效的陈述(它们都评估为True):

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

唯一可能看起来奇怪的是0. == False1. == True

另一方面,你仍然可以通过在比较它之前将你的值转换为str来重现python 2的作用(这也评估为True):

str(5) < 'hello'

如果你真的需要这种行为,你可以随时拥有一个将进行强制转换/比较的函数。这样你就可以保证不同类型的对象总是以相同的方式进行比较,这似乎是python 2中唯一的约束。

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

或者甚至更好,你可以只在需要时施放:

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

另一方面,正如评论中所建议的那样,在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))

1
投票

我之前已经在网上看过这个了,除了上面提到的几个特殊情况外,它们在Python 3中看起来确实不合算。

这种变化通常表现在排序列表中:在Python 3中,包含不同类型项目的列表通常不可排序。如果需要对异构列表进行排序或比较不同类型的对象,请实现一个关键功能,以完整地描述应该如何排序不同类型。 Source

我不知道为什么,但有些人找到了使用Python 3重现Python 2行为的方法。

也许你应该看看thisthatThis question还强调了2011年的变化:

找到它:埋在PEP 3100中:“不同类型之间的==和!=之外的比较将引发异常,除非明确支持类型”

© www.soinside.com 2019 - 2024. All rights reserved.