Python介绍
本节内容
- Python简史
- Python是一门什么样的语言?
- Python的优点与缺点
- Python解释器
一、Python简史
历史背景
在20世纪80年代,IBM和苹果已经掀起了个人电脑的浪潮。但是在今天看来,当时的个人电脑的配置都很低,以至于一个大的数组就能把内存占满。为了让程序能够运行,当时所有编程语言编译器的核心就是尽量的去做优化。为了提高程序运行效率,编程语言迫使程序员去像计算机一样思考,以便写出更符合计算机口味的程序。在那个时代,程序猿生活在水深火热之中,他们被迫去像资本家一样花费大量的时间和精力想尽一切办法去榨干计算机的每一寸能力。
Guido von Rossum,一个拥有阿姆斯特丹大学数学和计算机硕士双学位的荷兰人,他当时也是一个苦逼程序猿,并且他已经接触并使用过C语言。当时Guido面临的现状是:即使他已经准确的知道了如何用C语言去写出一个功能,整个编写过程还是需要耗费大量的时间,因为他要考虑“这样写计算机是不是喜欢”。这让Guido感到非常苦恼。Guido的另外一个选择是使用shell。Boure Shell 作为UNIX系统的解释器(interpreter)已经长期存在。UNIX的管理员们常常用shell去写一些简单的脚本,以进行一些系统维护的工作。shell可以像胶水一样,将UNIX下的许单一的多功能组合在一起去完成一些复杂的工作。许多C语言需要上百行代码才能完成的功能,在shell下只需要用几行代码。然而,shell的本质是调用命令,它并不是一个真正的编程语言。总之,shell不能全面的调动计算机的功能。
Guido非常希望有一种编程语言既可以像C语言那样能够全面地调用计算机提供的的功能接口,又可以像shelll那样可以轻松的进行编程。
Python的诞生
1989年,Guido为了打发圣诞假期(看来,这也是个做IT的单身宅...),他开始写Python语言的编译器/解释器。Python的名字来自Guido非常喜欢的电视剧 Monty Python's Flying Circus。他希望这个叫做Python的语言能够是他一直想要的编程语言--介于C和shell之间,功能全面、易学易用、可扩展。
1991年,Python正式发布第一个版本。该版本用C语言实现了第一个Python编译器(同时也是解释器),并且它能够调用C库(.so文件),这为python编写高效的C扩展模块提供了先天性的条件。
Python的发展
促进Python发展的两个主要原因
计算机性能提高
90年代初,个人计算机开始进入普通家庭。Intel发布了486处理器,windows发布了window 3.0开始的一系列视窗系统。计算机的性能大大提高,程序员开始关注计算机的易用性。
开源社区逐渐形成
1990年的个人电脑时代,许多程序员以及资深计算机用户已经在频繁使用Internet进行交流(包括email 和 newsgroup),这让信息交流成本大大下降。当时Unix的商业化让爱好开放、自由的IT从业人员感到崩溃,而GNU组织的成立促使一种新的软件开发模式开始流行:open source。程序员利用业余时间进行软件开发,并开放源代码。1991年,Linus在comp.os.minix新闻组上发布了Linux内核源代码,吸引了大批hacker的加入。Linux的出现之前,那些开源软件只能跑在他们深恶痛绝的已经商业化的UNIX系统上。这是很滑稽,也是让开源软件开发者们感到非常的郁闷的。Linux的出现,让他们重新找到了组织,Linux和GNU相互合作,最终构成了一个从满活力的开源平台。
Python各版本迭代
硬件性能不再是瓶颈,Python又容易使用,所以许多人开始转向Python。另外,Guido后来宣布Python遵循GPL协议,Python从此走上了开源的道路,并且在开源社区的参与下开始快速发展。
- 1989年,为了打发圣诞节假期,Guido开始写Python语言的编译器。他的愿望是:创造一种C和shell之间,功能全面,易学易用,可拓展的语言。
- 1991年,第一个Python编译器诞生。它是用C语言实现的,并能够调用C语言的库文件。从一出生,Python已经具有了:类,函数,异常处理,包含表和词典在内的核心数据类型,以及模块为基础的拓展系统。
- Granddaddy of Python web frameworks, Zope 1 was released in 1999
- Python 1.0 - January 1994 增加了 lambda, map, filter and reduce.
- Python 2.0 - October 16, 2000,加入了内存回收机制,构成了现在Python语言框架的基础
- Python 2.4 - November 30, 2004, 同年目前最流行的WEB框架Django 诞生
- Python 2.5 - September 19, 2006
- Python 2.6 - October 1, 2008
- Python 2.7 - July 3, 2010
- In November 2014, it was announced that Python 2.7 would be supported until 2020, and reaffirmed that there would be no 2.8 release as users were expected to move to Python 3.4+ as soon as possible
- Python 3.0 - December 3, 2008
- Python 3.1 - June 27, 2009
- Python 3.2 - February 20, 2011
- Python 3.3 - September 29, 2012
- Python 3.4 - March 16, 2014
- Python 3.5 - September 13, 2015
现状
Python得到广泛的认可和应用
自从2004年以后,Python的使用率呈线性增长。现在Python已经成为最受欢迎的程序设计语言之一。
2016年TIOBE编程语言排行榜图:
由上图可见,Python的使用率整体呈上升趋势,说明Python逐渐得到了业内的认可,并且得到了越来越广泛的应用。这得益于Python的简单易学,但个人认为更重要的原因在于两个方面:
- Python可扩展的模块化架构
- Python走上开源之路,开源社区中提供了大量的实用的第三方库
Python应用领域
Python现在被广泛用于众多领域:
-
系统运维 通过Python提供API能方便的进行系统维护和管理,Python已成为Linux系统下的标志性语言之一;
-
云计算 Python是目前云计算领域最火的语言,典型应用为OpenStack;
-
Web编程 出现了很多python的web开发框架,如django、tronado,flash等;Youtube、豆瓣、知乎、春雨医生等公司所有业务几乎都是用Python完成,另外python在google内部也被大量使用;
-
科学计算、人工智能 NumPy扩展提供了大量标准数学库的接口,其他的典型库还有SciPy、Matplotlib、Enthgout librarys、pandas;
-
文本处理 Python提供的re模块支持正则表达式,还提供SGML和XML分析模块;
-
数据库编程 程序员可以通过遵循Python DB-API(数据库应用程序编程接口)规范的模块与Microsoft SQL Server、Orace、DB2、MySQL、SQLite等数据库进行通信;此外,Python自带一个Gadfly模块,提供了
一个完整的SQL环境; -
网络编程 Python提供了丰富的模块支持socket编程,能方便快速地开发分布式应用程序;
-
图形处理 有PIL、Tkinter、PyQT等图形库支持,能方便进行图形处理;
-
其他 python可以用来做很多事其他的事情,如编写爬虫程序、多媒体应用、pymo引擎(AVG游戏引擎)
正在向Python 3.0过度
今天Python已经进入到3.0的时代。由于Python 3.0向后不兼容,所以从2.0到3.0的过渡并不容易。另一方面,Python的性能依然值得改进,Python的运算性能低于C++和Java(见Google的讨论),因此Python依然是一个在发展中的语言。
二、Python是一门什么样的语言?
编程语言从不同的角度可以进行不同的分类:
- 低级语言和高级语言
- 编译型语言和解释型语言
- 静态语言和动态语言
- 强类型定义语言和弱类型定义语言
每个分类代表什么意思呢?我们一起来看下
低级语言和高级语言
低级语言是从计算机的角度出发的计算机语言,无法独立于机器(特定的CPU体系结构)运行。最初的计算机程序都是用0和1的序列表示的,通过纸带打孔进行输入。这些0和1的序列称为机器指令,即无需翻译计算就可以直接执行的指令。后来为了方便记忆,就将用0、1序列表示的机器指令都用符号助记,这些与机器指令一一对应的主机符就成了汇编指令,从而诞生了汇编语言。机器指令和汇编指令都是面向机器的,统称为低级语言。
高级语言是从人类的逻辑思维角度出发的计算机语言,抽象程度大大提高,可以独立于机器运行。由于机器是无法理解人类的逻辑思维的,所有高级语言编写的指令需要经过转换成特定机器上的目标代码才能执行,且一条高级语言的语句往往需要若干条机器指令来完成。高级语言独立于机器的特性是靠编译器为不同机器生成不同的目标代码(或机器指令)来实现的。要将高级语言编译到什么程度是跟编译技术有关的,既可以编译成直接可以执行的目标代码,也可以编译成一种中间表示,然后拿到不同的机器和系统上去执行,这种情况通常又需要相应的支撑环境,比如解释器或虚拟机的支持。Java是一个很好的例子,Java源代码会先被编译成bytecode,再由不同平台上的虚拟机执行。所以高级语言不依赖于机器是指在不同的机器或平台上高级语言的程序源码本身不用改动,而通过编译器或解释器得到相应的目标代码区适用不同的机器。
编译型语言与解释型语言
两者的区别
上面提到,高级语言是从人类的逻辑思维角度出发的计算机语言,抽象程度大大提高,所有高级语言编写的指令需要被翻译成特定机器上的目标代码才能执行。这个翻译的过程可以由编译器来完成,也可以由解释器来完成,只是他们转换过程和时间不一样:
- 编译型语言 是通过编译器一次把所有代码全部翻译成机器语言,然后保存为可执行文件,下次可以直接运行,不用再次进行翻译;其运行过程是这样的:编译-->执行-->执行-->执行...,翻译和执行过程是分开的,典型语言是C语言、C++;
- 解释型语言 是在每执行到源程序的一条指令时,就要通过解释器将这条指令翻译成二进制代码以供执行,每次执行都要进行这个翻译过程;其运行过程是这样的:解释-->执行-->解释-->执行...,翻译和执行过程是一起完成的,典型语言是PHP,Javascript等;
这就好比你要阅读一本英文书,而你又不懂英文,你就需要一位翻译来帮助阅读。你相当于计算机,而英文书相当于源代码。你可以选择让这位翻译将这本英文书全部翻译成中文写在纸上之后交给你,这就是编译型;你也可以选择让这位翻译帮你阅读,但是你每次想看前面的内容就需要翻译帮你重新翻译一遍,这就是解释型。
两者的优缺点
编译型语言和解释型语言最大的不同体现在两个方面:
- 可移植性 解释型语言的程序总是以源代码的方式出现,因此只要有相应平台上的解释器,移植就几乎不是问题;编译型语言的程序虽然源代码可以移植,但是需要针对不同的平台进行分别编译才能执行;
- 执行速度 解释型语言编写的程序省却了编译步骤,因此修改调试非常方便,编辑完毕后即可立刻运行;但是解释型程序要想被计算机执行,还是需要被翻译成机器代码的,只是这个翻译的过程被放到了执行过程中,因此它的执行速度是比较慢的;而编译型语言编写的程序一个小小的改动都要重新编译,如果工程很复杂的话,这个编译过程是很漫长的;但是编译型程序仅仅是在修改后才需要被重新编译一次,之后执行时就可以直接执行了,因此它的执行速度是比较快的。
两者的融合
编译型语言与解释型语言各有优点和缺点,并且这些优缺点是相互对立的,所以一批新型的语言都有把两者折中起来的趋势。例如Java语言在执行之前需要进行预编译,但是这个预编译不是直接生成目标代码,而是介于机器码和Java源代码之间的中介代码(Java 字节码),然后由JVM(Java虚拟机,可视为解释器,详细解释可以参考这里)解释执行已达到提高执行速度的的目的;另外通过对不同平台实现对应的JVM解释器,使得Java字节码可以在任何有JVM的平台上被执行,这就实现了可移植型。
随着设计技术与硬件的不断发展,编译型与解释型这两种方式的界限正在不断的变得模糊。
静态语言与动态语言
通常我们所说的静态语言、动态语言是指静态类型语言和动态类型语言:
- 动态类型语言 在运行期间才去做数据类型检查的语言,典型语言:PHP、Python、Perl等;
- 静态类型语言 在编译期间进行数据类型检查的语言,典型语言:C/C++、JAVA、Ocamal等;
这里纠正一个误区:
很多人觉得C语言和JAVA等编程语言在定义变量时需要指定int、long这些数据类型,所以C和JAVA是静态语言;而Python不用指定数据类型,直接写变量名,所以Python是动态语言。这种理解是不够准确的,譬如Ocaml是静态类型的,但是也可以不用明确的将数据类型写出来。静态语言与动态语言最主要的区别在于:是在编译时检查变量数据类型还是再执行时检查数据类型,而不在于是否在定义变量指定数据类型。
强类型定义语言和弱类型定义语言
- 强类型定义语言 变量的数据类型不可以进行隐式转换的编程语言;
- 弱类型定义语言 变量的数据类型可以进行隐式转换的编程语言;
这里纠正一个误区:
很多人认为Python语言的一个变量可以多次赋值为不同数据类型的值,因此Python是弱类型的语言;C语言在定义变量时显式的指定了数据类型,因此C语言是强类型的语言。实际上,强类型语言与弱类型语言的主要区别在于对数据类型进行检查的严格程度,是否允许隐式类型转换。如C语言的int可以变成double,所以C语言是弱类型的,而Python实际上是强类型定义语言。
结论
同上上面的介绍,我们可以得出一个结论就是:Python是一门动态的、强类型定义的、解释性编程语言。
各类型编程语言举例:
- 无类型: 汇编
- 弱类型、静态类型 : C/C++
- 弱类型、动态类型: Perl/PHP
- 强类型、静态类型 :Java/C#
- 强类型、动态类型 :Python, Scheme
关于各种编程语言类型的区别,大家可以看下知乎上的这篇帖子。
三、Python优点与缺点
优点
-
简单易学、功能强大 python的定位时“优雅”、“明确”、“简单”,但是功能却很强大;
-
丰富的库、开发效率高 python有非常强大的第三方库,基本上你想通过计算机实现的任何功能,python官方库里都有相应的模块进行支持;在基础库的基础上进行开发,大大降低开发周期,提高了开发效率;
-
高级语言、抽象程度高 用Python编写程序的时候无需考虑过多底层细节,如如何管理程序使用的内存等;
-
面向过程、面向对象 Python及支持面向过程编程,也支持面向对象编程;在面向过程的语言中,程序是由过程或仅仅是可重用代码的函数构建起来的;而在面向对象的语言中,程序数据(属性)和功能(函数/方法)组合而成的对象构建起来的;
-
可移植性 由于它开源的本质、Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上);如果你小心的避免使用依赖于特定系统的特性,那么你的python程序无需修改就可以在几乎所有的系统平台上运行;
-
可扩展性 如果需要一段关键代码运行得更快或者希望某些算法不公开,可以将这部分程序用C/C++编写,然后再Python中调用。
-
可嵌入型 可以把Python嵌入C/C++程序中,从而实现向用户提供脚本的功能;
缺点
-
线程不能利用多CPU 这是Python被人诟病最多的一个缺点。Python的线程是操作系统的原生线程,在Linux上为pthread,在Windows上为Win thread,完全由操作系统调度线程执行。一个Python解释器进程内有一条主线程,以及多条用户程序的执行子线程。由于GIL(Global Interpreter Lock,全局解释器锁,它是计算机程序设计语言解释器用于同步线程的工具,使得任何时刻仅有一个线程在执行)的存在,使得即使在多核CPU平台上,还是会禁止多线程的并行执行。
-
代码不能加密 由于Python是一个解释型语言,其源代码都是以明文存在的。
-
执行速度慢 这里是指与C和C++相比,Python确实要慢很多,这是由语言特性确定的;另外Python比Java也会慢一点,JVM比PVM的实现更底层一些,因此JVM在将字节码翻译为机器码的速度也就更快一些。
-
多行语句与命令行输出问题 由于Python规定用缩进来表示代码结构,而不支持分号分割,因此在大多数情况下不能将多条程序语句写成一行;如果在shell下要使用多条python语句来完成一个功能时,必须将程序写入.py文件中。
小结
其实编程语言只是一个实现我们想法的工具,任何一门语言都有其擅长和不擅长做的事情。就像我们拿一个人的劣势和自己的优势去比较一样,拿一个语言的劣势去跟另外一个语言的优势去比较是没有任何意义的。我们不应该把太多时间和精力放在这些毫无意义的口舌之争上,那只能说明我们自己知识面太窄,水平还太low。
四、Python解释器
解释器的运行方式
解释器的概念比较简单,它可以将代码进行翻译并运行,不需要经过编译,JVM中的解释器就是这样的。解释器运行程序的方式有3种:
- 直接运行高级编程语言,如shell内置的解释器;
- 先将高级语言转换成一些效率更高的字节码(Bytecode),然后再解释执行这些字节码,这种解释器有两种翻译功能(源代码-->字节码,字节码-->机器二进制语言),如:CPython解释器;
- 以解释器中包含的特殊编译器对高级语言中间代码(如字节码)进行编译,然后指示处理器运行编译后的程序,如:PyPy解释器 和 JVM中的解释器(它们都包含一个JIT编译器,JIT编译器会将热点代码编译结果缓存起来,从而达到加块执行速度的目的);
Python的默认解释器CPython就是属于第二种,Python代码在第一次被执行时会被CPython解释器编译成运行效率更高的字节码,然后再逐条执行字节码指令。如果可以的话,Python的字节码会被保存到.pyc文件中,这样下次执行该代码时就可以直接解释运行字节码,而不用再去编译源码了。这与Java代码的执行过程很相似,但是Java的源代码编译成字节码的过程是由专门的编译器(javac)来完成的,JVM中只是字节码解释器和一个JIT编译器。可见这种机制正在模糊解释器和编译器之间的接线,或者说是模糊了解释型语言和编译型语言的界限。
Python解释器分类
事实上,Python规定了一个Python语法规则,实现了Python语法的解释程序就可以被称为Python解释器。由于Python语言从规范到解释器都是开源的,所以任何有能力的人都可以编写Python解释器,而且确实存在多种Python解释器:
-
CPython C语言实现的Python解释器,这个Python默认使用的解释器,也是使用最多的版本;从Python官方网站下载并安装好Python之后,我们就直接获得了一个官方笨的解释器CPython;
-
Ipython 它是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的;
-
Jython Java语言实现的运行在Java平台上的Python解释器,它可以直接调用Java的各种函数库,也可以把Python代码编译成Java字节码执行;
-
IronPython 面向.NET和ECMA CLI 的Python实现,它可以直接调用.net平台的各种函数库,也可以将Python程序编译成.net程序执行;
-
PyPy Python语言写的另一个Python解释器,它的目标是执行速度。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),所以可以显著提高Python代码的执行速度。
参考文章: