为什么Python用C而不是C ++编写?


76

Python的教程中,可以看到Python的原始实现是在C中实现的;

另一方面,用C编写的Python实现(...)

我很好奇为什么Python是用C而不是C ++编写的?

我想知道此决定的原因,答案应以历史参考为依据(而非基于观点)。


10
我不知道为什么,但是我怀疑这很接近:thread.gmane.org/gmane.comp.version-control.git/57643/… :)
Matthieu 2010年

13
@拉里·科尔曼:从来没有见过莱纳斯的咆哮?您必须避免使用“互联网” ...> _>
Hannibal Lecter博士

18
@Larry我确实看到了这种怒,并且在阅读它之后几乎失去了对Linus的尊重。可耻。
Piotr Dobrogost

5
好吧,这是对Linus 怒吼
avi

6
我看不出要问“为什么(流行的程序)用(语言X)而不是(语言Y)编写?”的意思。或更确切地说,可以颠倒相同的问题:为什么选择Y,而不选择X?
Andres F.

Answers:


119

从我所看到的一切来看,这是实践和历史原因的结合。(大多数)历史原因是CPython 1.0于1989年发布。当时,C刚刚被标准化。C ++几乎是未知的,而且绝对不可移植,因为几乎没有人拥有C ++编译器。

尽管C ++如今更加广泛且易于使用,但仍需要大量工作才能将CPython重写为与C ++兼容的C子集。就其本身而言,这项工作将几乎没有或没有真正的好处。

这有点像乔尔(Joel)的博客文章,关于重新开始并进行完全重写是软件公司可能犯的最严重错误。我要指出微软从Windows 3.0核心到Windows NT核心的转换,以及苹果从MacOS 9到Mac OS / X的转换来反驳。谁都没有杀死公司-但它们绝对是大型,昂贵,长期的项目。两者也都指出了对成功至关重要的事情:将这两个代码库维持足够长的时间,以便(大多数)用户可以(至少从感知上)受益于闲暇时切换到新的代码库。

但是,对于像Python这样大的开发团队来说,这种改变要困难得多。甚至从Python 2到3的更改也花费了很多工作,并且需要类似的重叠。但是,至少在那种情况下,更改有直接的好处,而改写C ++(本身)(至少立即)不会提供。

莱纳斯·托瓦尔兹(Linus Torvalds)对C ++的怒吼引起了人们的注意,所以我也要提一下。我从Guido看到的任何信息都没有表明他对C ++有那种强烈的消极情绪。我见过他说的最糟糕的情况是,教C ++通常是一场灾难 -但他立即继续说,这主要是因为老师不/不知道C ++。

我还认为,尽管可以相对轻松地将许多C代码转换为C ++,但要想从C ++中获得真正的优势,不仅需要进行大量重写,而且还需要对大多数相关开发人员进行大量培训。大多数写得很好的C ++与写得很好的C在做相同的事情上有本质的不同。这只是一个改变的事情mallocnew,并printfcout,通过的任何想象。


2
+1你引述很多;他们很有趣。似乎可以添加链接会更好。
n611x007 2012年

1
刚刚提交了带有Joel博客文章链接的修改内容joelonsoftware.com/articles/fog0000000069.html
MarkJ 2013年

这是一个很好的答案。我从中学到了很多。
Games Brainiac

1
+1专门提到可以相对轻松地移植到c ++的c可能不值得。我已经知道了很长时间,但是答案确实加强了观点,并增加了一些方面。
2013年

1
“ Apple从MacOS 9转换为Mac OS / X”注意到OS / X并非从头开始重写:它是从MacOS9到NeXTStep的切换,经过改进并重新命名为Apple
Jivan 2014年

30

我认为它最初是用ANSI C89编写的原因很简单,因为在那时,由于不同的编译器之间不兼容,所以C ++并不是可行的选择。我的意思是直到2005年才提出ABI规范,该规范允许使用一个编译器编译的代码调用使用其他编译器编译的代码?

更加有趣的问题是为什么它仍然使用C89编写。

有一个令人惊讶的答案:因为人们实际上在没有C ++和C99编译器的平台上使用Python!合并了受Forth启发的线程代码解释器优化时,对此进行了广泛的讨论,因为(必须)使用的代码goto是经过计算的,而不是C89的一部分。显然,人们确实担心该功能可能在当前使用Python的某些平台上不可用。

Unladen Swallow也发生了同样的事情,但使用的是LLVM,它是用C ++编写的。很清楚,将Unladen Swallow合并到CPython中的要求是您可以在没有JIT编译器的情况下进行编译,因为有些平台上运行Python,而C ++编译器不存在。

当然,如今,CPython不再是唯一的Python实现。有PyPy,它是用RPython(Python的静态类型子集),Java的Jython,C#的IronPython,NQP和PIR的Pynie编写的。


3
我很想提出支持,但是我不知道没有这样的平台可以使用C ++编译器(特别是考虑到Comeau C ++可以编译为C)
Billy ONeal

1
+1提及ABI
jk。

3
@Abdul:不,Python根本不是软件。这是一个规范。该规范有多种实现,用多种语言编写。IronPython是用C♯,Java的Jython,RPython的PyPy,NQP,PIR和Perl6的Pynie,C ++的Pyston以及C的CPython编写的。“ Python是用C编写的”语句是没有意义的。Python不是软件。这是一个规范。它是用英语写的,而不是任何编程语言。“ Java是C的派生”主要是错误的。Java受到Objective-C的启发,但是它摆脱了大部分C部分,并且大部分采用了Smalltalk部分。
约尔格W¯¯米塔格

3
@MilesRout:在很多情况下,规范都偏离CPython。例如:Python规范不保证确定性的终结,但CPython至少对于非循环引用可以保证。但是,即使CPython保证了非循环引用的确定性终结,但是依赖于该事实的代码编写也被破坏了,因为它不是规范的一部分。(我现在找不到报价,但是GvR明确表示确定性的确定和引用计数是CPython的内部内部实现细节。)
JörgW Mittag

2
同样,CPython保证两个Python线程不能并行执行,但是这也是CPython的内部私有实现细节,并且不受语言规范的保证。如果您说的是正确的,则不可能有任何其他实现,因为任何替代实现都必须与CPython行为相同,因此必须与CPython相同。(不会改变可观察行为的模块化重构。)
JörgW Mittag

10

一个更好的问题可能是:“为什么Python不是用Python编写的?”

更重要的是,一旦用C编写了足够的Python类和对象原语,就可以将其用于编写其余的解释器,因此使用C ++不会获得任何收益。


1
如果您点击答案中的第一个链接,将会看到对Python中Python实现的引用。那还没准备好生产。那是由欧盟资助的。codespeak.net/pypy/dist/pypy/doc是链接,如果它是很难从我的答案找出来。
vpit3833

2
这实际上是一个很深的答案。并不是说Guido的Python实际上是用Python编写的,而是C语言中的低级结构用来编写高级结构。
杰里米

1
我认为您没有理会这一点,因为(对于从事解释器本身的人员而言)解释器使用的语言存在很大差异。语言会影响这些原语的外观以及它们之间的交互方式。例如,现在,在Python的C实现中,必须记住手动增加和减少引用计数而为此可以在C ++中使用智能指针。
Piotr Dobrogost 2014年

现在PyPy可用了,有时有趣的是它的表现优于CPython,我认为这将是一个很棒的主意。
Sai Kumar Battinoju
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.