当前位置:   article > 正文

Python到底有没有编译器?_python编译器

python编译器

前言

简单地说,Python有编译,也有编译器。可比知道有没有更为重要的事情是,为什么说有。

一个技术通常有两个层面的东西,第一个层面是标准,第二个层面是实现。

【----帮助Python学习,以下所有学习资料文末免费领!----】

标准在于界定概念,明确概念的范围和边界,被视作一种规范,通常以规格说明说书或者协议文档的形式呈现。

实现在于将标准中定义的概念落到实处,能够直接被程序员拿来做开发与生产,通常以软件库、应用程序、服务的形式呈现。

Python技术自然也是有标准,有实现的。

对于经验比较浅的技术人员,标准和实现往往分不清。想来主要有以下的一些原因:

  1. 标准中的概念高度抽象,难以理解;
  2. 标准以文档为形式,对一个概念的验证手段复杂,经验浅的人知识储备不足,容易误解;
  3. 标准中的概念有边界,有留白,不同的实现会在此引入差异,造成误解;
  4. 实现虽然相对具体,但仍旧依托概念来描述;区分不清标准中的概念与实现中的概念;
  5. 实现门派林立、研发周期短,还有些非技术的因素参杂其中;
  6. 实现与标准中的概念虽有规范,定义严格,但不同人脑对其解释仍旧千差万别。

编译和编译器都是概念,解释和解释器也都是概念。先不谈标准和实现中用形式化语言描述的概念,而是要意识到,不精确的人脑中的感性认知的概念是千差万别的。在此需要先做些感性上的澄清。

编译这个概念的核心是翻译, 从一种语言翻译到另一种语言,重在说输出是不同于输入语言的第二种语言。

编译器是做翻译的一个工具。编译器通常理解为,接受源语言,产生目标语言,这样一个概念模型。因此,界定是不是编译器,就在于检查输入是不是一种语言,输出是不是另一种语言。说一个编程语言技术有没有编译器,会略复杂些,还是要从标准和实现两个层面看。

至此需要举例子来说明。说C/C++语言、Java语言有编译器,大家往往都没有异议。狭义地理解,C/C++语言的编译器有gcc[1]、clang[2]等,Java语言的编译器有javac[3]。gcc或clang接受的源语言不严格地讲是C或C++,产生的目标语言是汇编语言或者二进制机器语言。javac接受的源语言是Java,产生的目标语言是Java字节码。

不管gcc还是clang,相对C/C++语言的标准而言,都是实现,它们各自可以有自己的标准,但对C/C++的标准而言,它们标准也仍旧是实现。可见标准与实现是相对的,不是绝对的,只是站在哪个角度看的问题。

人们对C/C++或者Java有编译器的论断不会产生疑惑的原因在于,在语言标准层面,编译和解释就已经明确分离了。

Java语言有明确的Java语言规格规范[4]和Java虚拟机规范[5],一个描述源语言,另一个描述目标语言。技术是人为创造的,不能脱离了人和时代来看待技术。Java语言诞生之初为了解决程序语言在互联网中跨平台的问题,因此设计之初就将虚拟机的规范包含其中,分离语言规范和虚拟机规范也是Java语言能够获得巨大成功,广泛流行的重要原因之一。

C/C++情况复杂些。以下仅就C语言的情况做个举例说明。

C语言在1989年被美国国家标准协会(ANSI)标准化后,称作ANSI C。在1990年,国际化标准组织(ISO)采用了ANSI C的标准,标准化编号是ISO/IEC 9899:1990,俗称C90或者C89。后续的修订版本中,有C99、C11、C17、C2x等[6],均沿用了以修订年份后两位命名的传统。

在网上免费预览ISO/IEC 9899:2018(en)的章节目录,可以注意到C语言的标准中谈到了运行环境、语言和库。语言和库自不必说,是源语言的规范。运行环境一章(图1)第一节叫概念模型,即定义核心的概念来描述C语言的程序结构和程序运行环境。看第一节下面的两小节题目分别是翻译环境(Translation environment)和执行环境(Execution environments)。翻译环境用的单数,是标准化的,虽然实现可以多样,但实现中所实现的编译环境需要满足标准中定义的程序结构、编译阶段和调试方法等规范。执行环境用的复数,意在指出宿主机是多种多样的,比如MacOS、Linux的各种版本、Windows等等。可C语言的标准中仅仅做了些宿主机无关的环境要求,包括程序的启动、执行和终止,特别单列了多线程环境的规范。

在这里插入图片描述

图1 ISO/IEC 9899:2018(en)目录节选

从C语言的规范中可以得到两个结论:其一,C语言规范只规定了源语言的标准,不规定目标语言的标准;其二,C语言规范分节规定了翻译环境和执行环境。

这两条结论综合起来就是,翻译和执行可以分开做成两个部分,也是大部分实现所采用的。要说清楚为什么要分开,分开的好处是什么,涉及到工程实践中的开发管理和工程经济相关的理由了,在此不做赘述。

说到翻译和执行的分离,自然要说解释了。

解释这个概念的核心就是执行,将一种语言指令加载、读取,按照规范进行执行。处理器的本职工作,以及操作系统的进程模型的本职工作,就是执行一种语言的指令,用模糊、笼统、感性的词汇说就是解释。

解释器是一个执行工具。执行输入的指令,并且输出一些文本、声音、字节流等等。输入的指令形态,如果暴露给程序员,比如.obj、.dll、.class等等,那么人们往往认为编译器和解释器独立为两个东西;如果没有暴露给程序员封装在内部,那么就认为是对源代码的直接解释。可事实并非如此,编译器虽然没有单独拆出来做成一个可执行程序,但编译的过程在狭义的“解释器”的内部是不可能缺少的。

由此,说Java虚拟机是一个解释器,操作系统是个解释器,计算机中央处理器是个解释器,不够学术,不够精确,但认识上是清晰的、确切的。解释器不一定非要是狭义的JavaScript的V8那样的。

回到Python语言[7]。在语言的标准层面,可参考的标准是名为《Python语言参考》[8]的文档。浏览这个文档的目录,其中第四章执行模型和第五章导入系统跟解释比较相关(图2)。程序的结构和模块的导入都是围绕源程序的概念层面说的,并没有明确引入额外的编译环境等概念,这也是人们常认为Python是个解释型的语言的主要依据。

在这里插入图片描述

图2 《Python语言参考》的目录节选

编译在语言的标准层面定义的缺失并不意味着能没有编译。这些需要在实现层面去考虑。Python语言的实现层面变种很多[9],Guido van Rossum给出的实现被称作CPython,是Python语言的参考版本。引述原文[10]是这样说的:

CPython is Guido van Rossum’s reference version of the Python computing language. It’s most often called simply “Python”; speakers say “CPython” generally to distinguish it explicitly from other implementations.

单就CPython这个实现来讲,是有编译器的,且编译器的设计文档在此

Design of CPython’s Compilerdevguide.python.org/compiler/

开篇第一句话就说了“In CPython, the compilation from source code to bytecode involves several steps”。显然在CPython这个实现的模型中有bytecode,只是这不是Python语言标准的一部分,只是CPython这个实现中采用的一种方案。

最后,回到标准和实现这组概念上。它们的关系,如同科学与技术的关系,如同数学和物理的关系。建立起这样的意识对于看懂和查阅技术手册是重要的,远比知道Python到底有没有编译器来得重要。想要在这点上有更深入的思维训练,请阅读《UNIX环境高级编程》的第二章UNIX标准与实现。

读者福利:知道你可能对Python感兴趣,便准备了这套python学习资料

学习Python对于计算机专业的同学来说是很有必要的。Python是一种编程语言,它的应用范围很广,可以应用于大数据、AI、算法、爬虫、运维等领域。大学之前可以提前学Python帮助计算机专业的学生提升增加求职竞争力、拓展知识面。

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习等学习教程。带你从零基础系统性的学好Python!

零基础Python学习资源介绍

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/506233

推荐阅读
相关标签