比较不相关的类型

发布日期:2026-07-20 00:45:04  来源 : 杭州电子商务研究院    浏览量 :0
杭州电子商务研究院 发布日期:2026-07-20 00:45:04  
0

介绍

      >>> x = range(50)
>>> x < 20
    

x < 20的值是多少

我会为你消除悬念,这是假的

我知道,这对我来说也没有意义。我不知道将整数与列表进行比较在语义上意味着什么,但我想知道为什么 Python 将这种比较转换为False

我认为这个答案可能与即将进行的演讲有关。毕竟,<运算符的实现是由列表类型的小于 dunder 方法处理的。

假设

  1. 我的第一个想法是,<运算符正在与列表的len()进行比较,这会导致x < 51 True。结果:错误

  2. 也许 Python 使用的是列表的id。这在某种程度上是有道理的,因为每个对象都有一个唯一的 Long ID —— 一个理想的比较工具。结果:错误

      >>> id(x)
170461900
>>> x < 170461901
False
    

回到源头!

此时,这个谜团促使我下载了Python 2.7源代码。

我本可以搜索互联网来寻找快速解决方案,但我想花一点时间深入研究Python 2.7源代码。

我开始在列表对象中查找 '<' 的实现。这就是跟踪C函数指针和宏的乐趣开始的时候……

我将节省您的时间,仅提供我发现的内容的摘要。比较操作在default_3way_compare函数中结束。

以下代码片段通过确定我们的列表始终大于(而不是小于)所有整数来决定所有列表整数比较的结果:

      /* different type: compare type names; numbers are smaller */
if (PyNumber_Check(v))
    vname = "";
else
    vname = v->ob_type->tp_name;
if (PyNumber_Check(w))
    wname = "";
else
    wname = w->ob_type->tp_name;
c = strcmp(vname, wname);
if (c < 0)
    return -1;
if (c > 0)
    return 1;
    

惊讶?困惑?我两者都有。

惊喜!

经过进一步的研究,我发现比较是基于类型的实际名称!因此,在我们的例子中,List 的字母顺序大于Integer!这种模式在大多数类型比较中都存在。

这并不是我所希望的理由,但至少我们有一个答案。

不过,既然我们知道发生了什么,看看你是否能找出更多谜题的答案:

      >>> [] < ()
>>> [] < {}
    

剧透警告

List小于Tuple ,记住字母表中 'L' 位于' T' 之前,当然按照同样的逻辑 List小于Dict

复活节彩蛋

相比之下,没有一个真正 小的:

      /* None is smaller than anything */
if (v == Py_None)
    return -1;
if (w == Py_None)
    return 1;
    

Python 3

到目前为止,我一直在使用 Python 2.7。我想知道在这种情况下Python 3会做什么。

      >>> x = range(50)
>>> x < 20
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: range() < int()
>>> [] < ()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: list() < tuple()
>>> [] < {}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: list() < dict()
    

太棒了!如上所示,不相关的类型比较现在会导致 TypeError,这个结果比字母顺序更容易理解。所以这个小问题已经修复了。

当你将你出色的应用程序升级到Python 3时,比较完全不同的类型会导致解释器大声抱怨,这是应该的。然后,你就可以忘记你在本篇文章中学到的一切了。:)

建议阅读

如果你感兴趣的话,在我完成挖掘后,我发现了一篇很棒的stackoverflow 帖子,证实了上述所有研究。你也可以查看 Python文档来找到相同的答案。尽管如此,浏览 Python 源代码还是一次很有启发的经历。

附注:此实现是CPython的实现选择。使用其他 Python 实现(如pypy)的结果可能会有所不同。

以上内容来自杭州电子商务研究院推送
分享到:

长按或扫码识别 分享给好友

长按或扫码识别 分享给好友
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据