在C++和Python之间的平等意义上区别的根源是什么?

Cal*_*laf 14 c++ python

C++和Python之间"平等"的含义似乎存在着近乎哲学上的差异.我开始尝试用Python做一些在C++中非常困难的东西:当两个枚举类型只是一组整数的包装时,区分它们,但问题比枚举更广泛,因此现在题.

如果我用C++代码编写,如下所示

#include <iostream>

struct Foo {
    bool operator==(const Foo& foo) const { return this == &foo; }
};

struct Bar {};

int main() {
    Foo foo = Foo();
    Bar bar = Bar();
    if (foo == bar) std::cout << "ok" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我完全相信平等比较会失败.实际上,这是一个编译错误.你甚至无法比较两个对象,除非它们只是为了开始使用相同的类型.

然而,似乎" 在Python中存在很少(没有?)先例,用于平等比较会引发错误 ".

并且" 如果[对象]每次与[不同类型的对象]进行比较时都会提升,它将破坏它被添加到的任何容器 ".

的确,写作

class Foo(object):
    pass


class Bar(object):
    pass


foo = Foo()
bar = Bar()

if (foo == bar):
    print("equal")
Run Code Online (Sandbox Code Playgroud)

揭示了在比较本来应该无法比拟的对象时没有问题.

哲学上,这两种语言之间平等意义的区别在于什么?

更新

我发现这个关于Python的困惑的部分原因在于,到目前为止,每个特征的设计似乎都是为了"自然","直观",甚至是"人类" - 而不是这些可以首先定义.

但是考虑到你在一家杂货店的水果区,并问一个围裙的小伙子:"你能告诉我这些橙子是富士还是红美味?" 当然没有人能够理解以某种方式冒险回答的问题.所以问题是如何在比特和字节中提供"难以置信"的响应.

更新2

(对GiacomoAlzetta评论的评论太久了)我尊重你的意见.尽管如此,从这一点开始,我不会尊重一本关于Python的书,这本书没有专门用一章或至少一节来指出这3 < [1]是真的,这解释了这个背景(无论是历史的还是哲学的).动态类型并不意味着一个人如此非常走投无路(因为,例如,一个只有少数可用的名称'a','b'和'c')重用名称以获得非常不同的含义.最终,它甚至不是一个哲学问题,而是一个工程问题:如何消除或至少减少多个人在软件项目上合作的机会会在系统中引入错误?保持休眠的错误(因为语言是动态类型的 - 我们无法预测计算路径)比尖叫"错误"的错误要糟糕得多.

Tim*_*ers 30

Python的基本意图随着时间的推移而发生了变化.在开始时,直到Python 2开发的最后阶段,基本上可以比较任何两个对象.即使是没有直观意义的混合型比较,例如:

>>> 3 < [1]
True
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它实际上是被比较的类型的字符串名称,上面的结果是由于它,作为字符串,"int" < "list".这主要是由于误导(事后看来)企图对所有对象施加总排序.

展望到Python 3,意图改变,并开始与执行datetime模块类型(这是在Python 2中引入):混合类型<,<=,>,和>=比较是由缺乏直观的感觉是引发异常代替,而毫无意义的混合型==总是返回False和毫无意义的混合型!=始终True.

>>> import datetime
>>> n = datetime.datetime.now()
>>> n < 3
Traceback (most recent call last):
  ...
TypeError: can't compare datetime.datetime to int
>>> n >= 3
Traceback (most recent call last):
  ...
TypeError: can't compare datetime.datetime to int
>>> n == 3
False
>>> n != 3
True
Run Code Online (Sandbox Code Playgroud)

Python 3通常会努力"像那样".当然,也有例外.例如,在比较不同数字类型的对象(如整数和浮点数)时,它们通常被强制转换为封面下的常见类型.

我深深卷入了这些决定(并编写了datetime模块),所以你可以相信我.但至于什么C++意图,你将不得不问别人;-)

更多信息

我要补充一点,直到在Python 2中引入"丰富的比较",所有比较都通过cmp()协议进行汇总:在CPython实现中,比较两个对象返回其中一个整数[-1, 0, 1]. __cmp__()方法不知道其中<,<=,==,!=,>,和>=实际所需.因此,虽然早期不喜欢 "比较任何两件事,无论什么"原始设计,但在将丰富的比较纳入语言之前,技术上很难摆脱.然后它变得简单(如果单调乏味).

  • `1j <"hello"`在Python 2中是真的,但是,例如,`1j <2j`引发了`TypeError`.疯狂的;-)是Python 3改变方法的另一个原因(他们都提出了'TypeError`). (3认同)
  • Python中的大多数容器类型都不关心你在内容中混合类型的程度,而Python 3方法允许"明显的"成员资格测试按预期执行,无论它们实际上是多么混杂.Python 2的方法也是如此,但是那个"组成"的结果要比绝大多数程序实际上有用得多.我相信Python 3的方法达到了正确的平衡.但是因为我为这个结果做出了贡献,当然这就是我要说的;-) (2认同)