赞
踩
简单地说,Python有编译,也有编译器。可比知道有没有更为重要的事情是,为什么说有。
一个技术通常有两个层面的东西,第一个层面是标准,第二个层面是实现。
【----帮助Python学习,以下所有学习资料文末免费领!----】
标准在于界定概念,明确概念的范围和边界,被视作一种规范,通常以规格说明说书或者协议文档的形式呈现。
实现在于将标准中定义的概念落到实处,能够直接被程序员拿来做开发与生产,通常以软件库、应用程序、服务的形式呈现。
Python技术自然也是有标准,有实现的。
对于经验比较浅的技术人员,标准和实现往往分不清。想来主要有以下的一些原因:
编译和编译器都是概念,解释和解释器也都是概念。先不谈标准和实现中用形式化语言描述的概念,而是要意识到,不精确的人脑中的感性认知的概念是千差万别的。在此需要先做些感性上的澄清。
编译这个概念的核心是翻译, 从一种语言翻译到另一种语言,重在说输出是不同于输入语言的第二种语言。
编译器是做翻译的一个工具。编译器通常理解为,接受源语言,产生目标语言,这样一个概念模型。因此,界定是不是编译器,就在于检查输入是不是一种语言,输出是不是另一种语言。说一个编程语言技术有没有编译器,会略复杂些,还是要从标准和实现两个层面看。
至此需要举例子来说明。说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!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。