将Python编译为中间字节码(pyc)然后执行。所以,有一个汇编,然后是解释。但是,长期使用Python的用户认为Python是一种“后期绑定”语言,它不应该被称为解释语言。
Python与其他解释语言有何不同?
你能告诉我在Python上下文中“后期绑定”是什么意思吗?
Java是另一种语言,它首先将源代码编译成字节码,然后解释为字节码。
Java是一种解释/编译语言吗?
在编译/执行方面与Python有什么不同?
据说Java没有“后期绑定”。这与Java程序比Python快得多吗?
如果你能给我链接到人们已经讨论过的地方,那就太好了。我想更多地了解这一点。谢谢。
答案 0 :(得分:9)
Python与其他解释语言有何不同?
这涉及头发分裂。解释语言和“托管代码”语言(如C#和虚拟机语言(如Java))构成了一个奇怪的连续体。有些人会说所有语言都被“解释” - 甚至是机器语言。毕竟,CPU的电子电路“解释”机器语言。
你能做的最好的事情就是说“解释”意味着有一个可见的软件层解释你的应用程序字节码。 “未解释”表示您的软件(或多或少)直接由底层硬件执行。 “托管代码”人们可以自由地分开这头发。
你能告诉我在Python上下文中“后期绑定”是什么意思吗?
变量未声明具有类型。变量尽可能晚地绑定到一个类型 - 赋值实际对象。
Java是解释/编译语言吗?
是。它被编译为字节代码。解释字节代码。我更喜欢称之为解释。
然而,人们会(出于非常模糊的原因)不同意。存在任何类型的“编译”步骤 - 无论多么微小 - 总是让人感到困惑。字节代码的转换几乎与运行时程序的实际行为无关。有些人喜欢说仅语言完全可以解释任何预处理“编译”的污点。由于许多语言都是从人性化的文本转换为解释器友好的字节代码,因此不再有这么多的例子。甚至Applesoft Basic(早在80年代)就已经在输入代码时完成了这种翻译传递。
一些JVM做JIT。有些人没有。有些是混合物。要说JVM只进行JIT字节码转换是不正确的。有些JVM可以。有些人没有。
在编译/执行方面与Python有何不同?
完全没有。 Java VM可以执行Python。 [对于容易混淆的,在这种情况下,“python”这个词不可能意味着“python源”。它必须意味着python字节码。]
据说Java没有“后期绑定”。这与Java程序比Python快得多吗?
也许。由于JIT编译器在运行时将Java字节代码转换为机器代码,因此Java程序通常更快。
静态(“早期”)绑定与Java没有相同的好处,它具有真正的编译语言,如C或C ++,几乎没有任何类型的运行时检查。 Java仍然会执行数组边界检查等操作,但为了原始速度,C省略了它。
“迟”绑定实际上没有什么惩罚。使用简单的字典查找解析Python属性和方法。字典是哈希;表现相当不错。可以将名称的哈希值放入“实习”字符串文字池中,以分摊计算哈希值的成本。
真正有趣的是,看看PyPy和RPython。这是一个可以进行JIT编译的Python解释器。你结束了2层翻译。您的代码由PyPy解释。 PyPy由RPython解释。 http://alexgaynor.net/2010/may/15/pypy-future-python/
答案 1 :(得分:7)
后期绑定是一种与解释截然不同的概念。
严格地说,解释语言是直接从源执行的。它没有经过字节码编译阶段。之所以产生混淆,是因为python程序是一个解释器,但是它解释了字节码,因此它是Python的字节码语言,你将其描述为“解释”。 Python语言本身就是一种编译语言。
相反,Java字节码现在被解释和编译。它由JIT编译器编译成本机代码,然后直接在硬件上运行。后期绑定是类型系统的一个属性,在某种程度上存在于大多数语言中,无论它们是否被解释或编译。
答案 2 :(得分:3)
我们称之为绑定时间与解释/编译的概念之间存在联系。
绑定时间是符号表达式绑定到其具体值的时间。这与编程语言的定义更相关,例如变量的动态范围与静态范围。或静态方法与虚拟方法或动态类型与静态类型。
然后是语言的实现。预先静态知道的信息越多,编写编译器就越容易。相反,语言越晚,越难。因此有时需要依赖解释技术。
然而,两者之间的区别并不严格。我们不仅可以认为一切都是最终解释的(参见S.Lott答案),但部分代码可以动态编译,反编译或重新编译(例如JIT),使得区分非常模糊。
例如,Java中的动态类加载属于“后期绑定”类别:类的集合不是一次修复的,并且可以动态加载类。当我们知道类集时,可以进行一些优化,但是一旦加载了新类,就需要使其无效。使用调试基础结构更新方法的能力也是如此:如果方法已经内联,JVM将需要对所有调用站点进行去优化。
我对Python知之甚少,但Python从业者更喜欢“后期限制”一词来避免这种混淆。
答案 3 :(得分:2)
我认为在Java编译时解释Python的常见误解是因为Java有一个明确的编译步骤 - 您必须运行javac将.java源文件转换为可以运行的.class字节码文件。
正如你正确地指出Python类似地将源文件编译成字节码但它透明地执行 - 编译和运行通常在一个步骤中完成,因此对用户来说不那么明显。
重要的区别在于早期和早期之间。后期绑定和动态&静态打字。编译/解释的区别毫无意义且无关紧要。
答案 4 :(得分:0)
绑定时间是名称解析为事物的时间。 更动态的语言倾向于后期绑定。 这可以与解释/编译分开 - 例如, 与C ++相比,objective-C方法延迟解决并动态解决。 Java在类加载时完成大部分绑定:比C更晚 早于Python。
my favorite quote from Stan Kelly-Bootle's Computer Contradictionary:
绑定时间哈希表损坏的那一刻。
==>计算的进步可以映射到“约束的迟到”,这让我想到了我自己所谓的CS所谓的职业生涯:黄金过去,灰色礼物和美好未来。这是我对Synge的乐观态度的版本:草除了在t = 0时更绿。在EDSAC I上,我的功能(5ch纸带子程序)在输入前大约两周被打孔,拼接和装订。这被称为过早绑定,并要求使用松紧带进行灵活性。接下来FORTRAN带来了一种新的绑定方式:拒绝洗牌的湿漉漉的牌组。然后使用Algol和C,我喜欢静态(编译时)绑定,直到C ++带来了动态(运行时)绑定的麻木乐趣。我目前的研究旨在延迟绑定,直到执行后。正如圣马太福音中所预言的那样,我称这种结束时为约束:“......无论你在地上所捆绑的一切都将在天上受约束......”(马太福音16:19)。