《怕蛇的人怎么学Python》:Python简介

1 min read

在学习任何一门编程语言前,最好先学习下这门语言产生的发展历史,通过发展历史去了解为什么会产生此语言?它主要为了解决什么问题?它的设计理念是什么?它吸收了哪些语言的特性?与其他语言相比它的优缺点在哪里?

Python的起源

Python的最初设计者是吉多·范罗苏姆(Guido van Rossum),1956年,他1982年出生于荷兰,从阿姆斯特丹大学获得了数学和计算机硕士学位。1986年时在荷兰阿姆斯特丹的国家数学和计算机科学研究学会(CWI)工作,并参与到ABC语言的开发。

ABC语言以教学为目的。与当时的大部分语言不同,ABC语言的目标是“让用户感觉更好”。ABC语言希望让语言变得容易阅读,容易使用,容易记忆,容易学习,并以此来激发人们学习编程的兴趣。比如下面是一段来自Wikipedia的ABC程序,这个程序用于统计文本中出现的词的总数:

HOW TO用于定义一个函数。ABC语言使用冒号和缩进来表示程序块。行尾没有分号。for和if结构中也没有括号()。赋值采用的是PUT,而不是更常见的等号。这些改动让ABC程序读起来像一段文字。

ABC的设计者声称的ABC的主要特点:

  • 只有五个基本的数据类型(数字、文本、列表、元组、字典)
  • 不需要声明变量的类型
  • 明确支持自上而下的编程(从整体到局部)
  • 程序的嵌套逻辑通过缩进控制
  • 无限的算数精度,无限大小的列表和字符串以及其他特性(正交性、新手一用等)

尽管已经具备了良好的可读性和易用性,ABC语言最终没有流行起来。在当时,ABC语言编译器需要比较高配置的电脑才能运行。而这些电脑的使用者通常精通计算机,他们更多考虑程序的效率,而非它的学习难度。除了硬件上的困难外,ABC语言的设计也存在一些致命的问题:

  • 可拓展性差。ABC语言不是模块化语言。如果想在ABC语言中增加功能,就必须改动很多地方。
  • 不能直接进行IO。ABC语言不能直接操作文件系统。尽管可以通过诸如文本流的方式导入数据,但ABC无法直接读写文件。输入输出的困难对于计算机语言来说是致命的。
  • 过度革新。ABC用自然语言的方式来表达程序的意义,比如上面程序中的HOW TO 。然而对于程序员来说,他们更习惯用function或者define来定义一个函数。同样,程序员更习惯用等号来给变量赋值。
  • 传播困难。ABC编译器很大,必须被保存一个很大的磁盘上。这样,ABC语言就很难快速传播。

1989年,为了打发圣诞节假期,Guido van Rossum决心开发一个新的脚本解释程序,作为ABC语言(本身受到 SETL 语言的启发)的一种继承。之所以选中Python作为程序的名字,是因为他是BBC电视剧——Monty Python’s Flying Circus的爱好者。就Guido van Rossum本人看来,ABC这种语言非常优美和强大,是专门为非专业程序员设计的。但是ABC语言并没有成功,究其原因,吉多认为是非开放造成的。

Guido van Rossum知道如何用C语言写出一个功能,但整个编写过程需要耗费大量的时间,即使他已经准确的知道了如何实现。他的另一个选择是shell。Bourne Shell作为UNIX系统的解释器已经长期存在。UNIX的管理员们常常用shell去写一些简单的脚本,以进行一些系统维护的工作,比如定期备份、文件系统管理等等。shell可以像胶水一样,将UNIX下的许多功能连接在一起。许多C语言下上百行的程序,在shell下只用几行就可以完成。然而,shell的本质是调用命令。它并不是一个真正的语言。比如说,shell没有数值型的数据类型,加法运算都很复杂。总之,shell不能全面的调动计算机的功能。

他希望这个新的叫做Python的语言,能符合他的理想:这种语言能够像C语言那样,能够全面调用计算机的功能接口,又可以像shell那样,可以轻松的编程。创造一种C和shell之间,功能全面,易学易用,可拓展的语言,对UNIX/C程序员有吸引力的语言。

1991年,第一个Python编译器诞生。它是用C语言实现的,并能够调用C语言的库文件。从一出生,Python已经具有了:类,函数,异常处理,包含表和词典在内的核心数据类型,以及模块为基础的拓展系统。Python语法很多来自C,但又受到ABC语言的强烈影响。来自ABC语言的一些规定直到今天还富有争议,比如强制缩进。但这些语法规定让Python容易读。另一方面,Python聪明的选择服从一些惯例,特别是C语言的惯例,比如等号赋值。Guido认为,如果“常识”上确立的东西,没有必要过度纠结。

Python从一开始就特别在意可拓展性。Python可以在多个层次上拓展。从高层上,你可以直接引入.py文件。在底层,你可以引用C语言的库。Python程序员可以快速的使用Python写.py文件作为拓展模块。但当性能是考虑的重要因素时,Python程序员可以深入底层,写C程序,编译为.so文件引入到Python中使用。Python就好像是使用钢构建房一样,先规定好大的框架。而程序员可以在此框架下相当自由的拓展或更改。

Python的设计哲学

1999年,Guido van Rossum向DARPA提交了一条名为“Computer Programming for Everybody”的资金申请,并在后来说明了他对Python的目标:

  • 一门简单直观的语言并与主要竞争者一样强大
  • 开源,以便任何人都可以为它做贡献
  • 代码像纯英语那样容易理解
  • 适用于短期开发的日常任务

这些想法中的一些已经成为现实。Python已经成为一门流行的编程语言,尤其是在互联网环境下。

与其他编程语言不同,Python并没有把所有功能特性都嵌入到它的核心代码中。Python 的设计是高度可扩展。由于看到ABC语言的失败,Guido van Rossum认为“小的核心语言”+“大的标准库”才是他需要的。当Python想要添加新功能时,更多思考的是改将此特性加入核心语言支持还是作为扩展放入库中。

在语法层面,Python拒绝了强大并复杂的语法(比如Perl的语法),而倾向于一种更简单、更简洁的语法。Python 的哲学拒绝 Perl”语言设计的方法不止一种”,而倾向于”应该有一种——最好只有一种——显而易见的方法”。

Python 的开发人员努力避免过早优化,并拒绝对 CPython 的非关键部分进行补丁,这些补丁将以成本为代价,提供边际增长速度。

Python的设计哲学是“优雅”、“明确”、“简单”。Python开发者的哲学是“用一种方法,最好是只有一种方法来做一件事”,也因此它和拥有明显个人风格的其他语言很不一样。在设计Python语言时,如果面临多种选择,Python开发者一般会拒绝花俏的语法,而选择明确没有或者很少有歧义的语法。这些准则被称为“Python格言”。在Python解释器内运行import this可以获得完整的列表。

翻译成中文为:

Python的发展

Python早期版本

Python的第一个最早期版本是0.9版本,于1991年2月20日发布,在发行的代码中说明中是这样介绍自己的:

Python作为一个解释性的编程语言,结合了清晰的语法和非凡的力量。它可以用来提到替代shell、Awk和shell来编写真实应用的原型或作为大型系统的扩展语言。并内置了操作系统和窗口系统的接口。

在此版本中,主要包含如如下特性:

  • 继承、异常处理、函数、核心数据类型(列表、字典、字符串)
  • 来自于Modula-3的模块系统(异常处理也是来自与Modila-3)

Python 1时代

1994年,Python发布了1.0版本,在该版本的源代码的介绍中它是这样给新人介绍自己的:

Python是一种解释性交互式、面向对象的编程语言。它包含了模块、异常处理、动态类型和高层次的动态数据类型和类。Python结合了清晰的语法和非凡的力量,它包含了许多系统调用的库,并且可以使用C或者C++进行拓展需要的接口,并且Python可以在许多品牌的Unix、Mac和MS-DOS上运行。

在该版本中还对Tcl/Perl的使用这进行了特殊的介绍:

Python是我在阿姆斯特丹开发的一种较新的高级语言。它是一种简单的、面向过程的语言,并且从ABC, Icon, Modula-3,和 C/C++吸收了很多的特性。它的核心目标主要有以下两点:

  • 提供像Perl/TCL/REXX一样的动态语言支持
  • 提供像Icon, C, Modula,…等传统编程语言的功能

因此,Python可以作为脚本/扩展语言、快速原型语言活一款正式软件的开发语言。Python适合快速的开发大型程序也适合编写类似shell一样可以用完即删的简短脚本。

Python的一些与其他语言类似的特性:

  • 动态的、解释性的、交互式的
  • 无需进行显式的编译或链接
  • 不需要声明类型(它是动态类型)
  • 更高级的操作符(比如‘in’操作)
  • 自动分配和释放内存(没有‘指针’)
  • 更高级的类型:列表、元组、字符串和关联数组(备注:字典)
  • 可以直接执行字符串的代码(无需编译成二进制)
  • 可以快速的编辑、编译和运行,没有静态链接
  • 与C函数和数据间定义好了非常好的接口
  • 可以方便的讲C语言模块添加到程序或语言中

另外一些新的特性可以帮助你更高的编程:

  • 它是面向对象的,它实现了C++ ‘class’的一个子集,并且使用了Python的动态类型(语言从一开始就实现了面向对象)
  • 它支持模块导入(就像Modula-3导入包一样),模块替代了C语言中的’include’方法和 文件链接,并且支持多模块及代码共享等。
  • 它有一个很好的异常系统(可以通过’try’和’raise’自定义异常)
  • 语言符合正交性,它所有的一级对象(方法、模块、类、包含方法的类)都可以被正常的分配/传递和使用
  • 它运行时相当安全,它做了很多运行时的检查,比如索引是否越界等,而C语言通常不会
  • 它支持常见的数据结构,比如Python的列表是支持异构(列表中的元素类型可以不一样)、可变长度、可嵌套,支持切片、可链接等,并且支持自动回收,字符串和字典同样类似。
  • 它包含了一个语法调试器和分析器,以及一个交互式命令行界面,就像在lisp中一样,在命令行中可以单独输入代码和函数进行测试(甚至链接到C语言的方法)
  • 它包含了一个巨大的内置模块哭,它支持 sockets、正则表达式、posix bings等。
  • 在许多平台上支持动态载入C模块
  • 它包含了一个可读性非常强的语法,Python的代码看起来非常的简单,不像TCL和Perl那么难理解

Python并不完美,但它是一个在脚本语言和传统语言间很好的折中方案。“完美”的语言在现实世界中并不一定有用(比如Prolog),一个语言在某一领域有空并不代码在另外一领域有用(C对于shell编码和原型设计来说很差,而awk对于大型系统设计是没有什么用到的,Python两者都可以做得很好)

Python使用基于缩进的语法,这种语法对于熟悉C语言的程序员最初可能看起来很不寻常,但在使用它之后我发现它非常方便,因为打字的次数减少了。

在1.0时代,主要加入的特性有:

  • 参考了lisp语言,引入了函数式编程工具lamda,map,filter和reduce。
  • 引入了受Modula-3启发的关键词参数(与Common Lisp 的关键字参数类似)
  • 支持复数
  • 引入了名字修饰和对象掩藏
  • 增加了unicode的支持,添加了一个基本的数据类型:unicode字符串

Python 2时代

Python的版本号在在2000直接从1.5.2变成了2.0。与Python 2.0一同发布的还有 1.6版本。Python 1.6可以被认为是完成契约义务 Python 的发布。 2000年5月,在核心开发团队离开 CNRI 之后,CNRI要求将在CNRI已开发的内容发布到1.6版本。其中,最重要的新特性是 Unicode 支持。当然,5月之后Python 1.6开发仍在继续,以确保它与 Python 2.0兼容。2.0中最重要的变化可能根本不是代码,而是 Python 是如何开发的: 在2000年5月,Python 开发者开始使用 SourceForge 提供的工具来存储源代码、跟踪 bug 报告以及管理补丁提交的队列。 要报告错误或者提交 Python 2.0的补丁,请使用 Python 项目页面中的 bug 跟踪和补丁管理工具。另外还参考了互联网RFC进程,建立了一个相对正式的过程来编写Python增强方案(PEPs)。PEP全称是Python Enhancement Proposal,翻译成中文是Python改进提案。它是Python记录Python变化的书面文档。

Python 2.0以来新增的一些比较重要的语言特性:

  • 增加了unicode的支持
  • 参考STEL和Haskell,引入了列表推导式
  • 增加了自动化管理内存的循环检测垃圾收集器
  • 更改语言规范以支持嵌套作用域
  • 将Python的数据类型(用C编写的数据类型)和类(用Python编写的数据类型)统一到一个层次中,使Python完全面向对象。
  • 参考Icon,引入了迭代器与生成器
  • 引入了函数/方法装饰器
  • 引入了with 语句,该语句将代码块包含在上下文管理器中,用于替换try/finally语法

Python3 时代

Python的3​​.0版本,常被称为Python 3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。为了不带入过多的累赘(纠正语言中的基本设计缺陷),Python 3.0在设计的时候没有考虑向下相容。为了照顾现有程式,Python 2.6作为一个过渡版本,基本使用了Python 2.x的语法和库,同时考虑了向Python 3.0的迁移,允许使用部分Python 3.0的语法与函数。类似地,Python 2.7与 Python 3.1,的特性相吻合,Python 2.7是2.x 系列中的最后一个版本。2014年11月,Python 2.7被宣布支持到2020年,但是用户被鼓励尽快转移到 Python 3。

Python 3 开发的重点是清理代码库并删除冗余,清晰地表明只能用一种方式来执行给定的任务。对 Python 3.0 的主要修改包括:

  • 统一了字符编码支持。Python 2中有 ASCII str()类型,unicode是单独的,不是byte类型。Python3中,字符串统一是unicede(utf-8)类型,以及一个字节类:byte 和 bytearrays。
  • 增加了新的语法。print/exec等成为了函数,格式化字符串变量类型标注,添加了nonlocal、yield from、async/await矩阵乘法操作符@、yield for关键词和__annotations__、__context__、__traceback__、__qualname__等dunder方法。
  • 修改了一些语法。metaclass,raise、mapfilter以及dict的items/keys/values方法返回迭代对象而不是列表,整除符号变更,描述符协议,保存类属性定义顺序保存关键字参数顺序
  • 去掉了一些语法。cmp、<>(也就是!=)、xrange(其实就是range)、不再有经典类
  • 增加一些新的模块。futures、venv、unittest.mockasyncioselectorstyping
  • 修改了一些模块。主要是对模块添加函数/类/方法(如lru_cache、threading.Barrier)或者参数。
  • 模块改名。把一些相关的模块放进同一个包里面(如httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib放进了http里面,urllib, urllib2, urlparse, robotparse放进了urllib里面),个例如SocketServer改成了socketserver,Queue改成queue等
  • 去掉了一些模块或者函数。gopherlib、md5、nested、inspect.getmoduleinfo等。去掉的内容的原因主要是2点:1. 过时的技术产物,已经没什么人在用了;2. 出现了新的替代产物后者被证明存在意义不大。理论上对于开发者影响很小。
  • 优化。重新实现了dict可以减少20%-25%的内存使用;提升pickle序列化和反序列化的效率;OrderedDict改用C实现;通过os.scandir对glob模块中的glob()及iglob()进行优化,使得它们现在大概快了3-6倍等..
  • 其他。构建过程、C的API、安全性等方面的修改,通常对于开发者不需要关心。

Python学习资料

参考链接:

最后欢迎关注公众号:怕蛇的人怎么学Python

打赏作者
微信支付标点符 wechat qrcode
支付宝标点符 alipay qrcode

C语言学习:size_t

在学习C语言的时候,遇到了一个新的数据类型size_t,截止目前也没有完全理清这个类似的具体场景及出现的原因。
44 sec read

C语言学习:main()函数的正确写法

C语言虽然是一门古老的语言,但是其标准一直在完善,所以很多以前支持的语法在到当前已经不能在使用了。 C语言的版
41 sec read

Scipy数学函数的Scala实现

最近在推进项目的时候,遇到需要将线下的Python代码转化成线上的集群代码,由于机器代码环境是Scala,所以
4 min read

发表评论

电子邮件地址不会被公开。 必填项已用*标注