Python 的历史
Python 是一种面向对象的解释型计算机程序设计语言,由荷兰人 Guido van Rossum 于1989年设计,并于1991年公开发行第一个发行版。
1982年,Guido 从阿姆斯特丹大学(University of Amsterdam)获得了数学和计算机硕士学位。然而,尽管他算得上是一位数学家,但他更加享受计算机带来的乐趣。用他的话说,尽管拥有数学和计算机双料资质,他总趋向于做计算机相关的工作,并热衷于做任何和编程相关的活儿。
1989年,为了打发圣诞节假期,Guido 开始写 Python 语言的编译/解释器。Python 的名字来自 Guido 所挚爱的电视剧 Monty Python’s Flying Circus (BBC 1960-1970 年代播放的室内情景幽默剧,以当时的英国生活为素材)。他希望这个新的叫做 Python 的语言,能实现他的理念(一种 C 语言和 shell 脚本之间、功能全面、易学易用、可扩展的语言)。Guido 作为一个语言设计爱好者,已经有过设计语言的(虽然不是很成功)的尝试。这一次,也不过是一次纯粹的 hacking 行为。(再次说明多给程序员放假的重要性!)
然而,时过境迁,Python 从 2000 年发布的 2.0 版本,到 2010 年的 2.7 版本,再到如今的 3.x 版本,Python 在各行各业的应用越来越广泛了。无论在自动化运维、Web 领域、数据挖掘与分析,还是机器学习与人工智能,甚至是教育行业都大放异彩。正如它的 slogan:人生苦短,我用 Python。
我觉得在互联网时代,不管你从事什么行业和岗位,都应该学一下 Python,是不是?
噢!你还需要知道的是,Python 2.7 是最后一个 2.x 版本,截止本文编写时,最新发布的版本是 Python 3.7.0。但是需要注意的是,Python 3.x 并不兼容 Python 2.7。虽然 Python 2.7 依旧被广泛使用,但建议初学者还是直接上手 3.x 吧。毕竟官方已经宣布停止对 Python 2.7 的开发,并于 2020 年停止支持。OK,那开始学习吧~
Python 的安装与运行
Python 的安装很简单,找到官网的下载页面,选择你所使用的平台和 Python 版本下载即可。
如果是 Ubuntu,可以使用 apt-get 下载;如果是 CentOS,可以使用 yum 下载;如果是 MacOS,可以使用 brew 下载。这种方式的好处是安装快且不用考虑依赖问题,坏处是如果没有更新源的话,下载安装的 Python 可能比较老旧(这取决于你的操作系统)。
安装完成后,你会得到一个 Python 交互式命令行环境。因为 Linux/Unix 系统自带 Python 2.7,所以你通常需要使用 Python3
命令来启动解释器。此外,你还可以安装 ipython3 命令行工具,它是前者的增强版,有更多的提示和交互特性。
如果是 Windows 系统,还会得到一个叫 IDLE 的可视化工具,你可以使用 IDLE 来编写并运行 Python 代码。此外,还有很多优秀的 Python 开发集成环境,最 666 的应该就是 PyCharm 啦,使用优秀的 IDE 能大大提高后续开发的效率。
查看官方文档
Python 的设计者才是最了解 Python 的,所以我们要学会查看官方文档。
其中,《The Python Language Reference》(Python 语言参考手册),描述的是 Python 的语法和核心语义。《The Python Standard Library》(Python 库参考手册)是随 Python 发布的标准库的使用说明。
跨平台特性
Python 的解释型语言特性决定了它天生是跨平台的。Python 的解释器有很多,使用最广泛的依然是 C 语言实现的 CPython。除此之外,还有 Java 实现的 Jython 和 .Net 实现的 IronPython 等等。
需要注意的是,虽然 Python 是跨平台的,但是 Python 的一些包却不是跨平台的。比如 GUI 模块,可能依赖于 SDL、GTK、Qt、Java,甚至是 Windows 环境的,这时候就需要根据不同的平台做调整。
编码
Python 3.x 相比于 Python 2.7 最大的一个改变就是使用 Unicode 作为默认编码。Pyhton 2.x 中直接写中文会报错,而 Python 3.x 中可以直接写中文了,并且允许使用中文作为变量名(但不推荐)。
因此,如果你看 Python 2.x 的代码,可能经常会遇到文件头有如下声明,用于指定 UTF-8 编码。
# -*- coding:utf-8 -*-
从开源项目看,支持 Python 3.x 的比例已经大大提高,通常知名的项目都会支持 Python 2.7 和 Python 3.x。
标识符 & 关键字
在 Python 中,标识符由字母、数字和下划线组成,但不能以数字开头,并且字母是区分大小写的。
(敲黑板!!!)
值得注意的是,下划线在 Python 标识符中有特殊的意义:
- 以单下划线开头
_foo
的代表不能直接访问的类属性,需要通过类提供的接口进行访问,不能用from xxx import *
而导入;- 以双下划线开头的
__foo
代表类的私有成员;- 以双下划线开头和结尾的
__foo__
代表 Python 里特殊方法专用的标识,如__init__()
代表类的构造函数。
Python 的关键字也称为保留字,我们不能用关键字作为标识符名称。那我们怎么知道 Python 里面有哪些关键字呢?
使用 keyword 模块来查看:
>>> import keyword
>>> keyword.kwlist
['False','None','True','and','as','assert',
'break','class','continue','def','del',
'elif','else','except','finally','for','from',
'global','if','import','in','is','lambda',
'nonlocal','not','or','pass','raise','return',
'try','while','with','yield']
模块导入机制
关于“模块导入”,Python 官方给出的解释是这样的:
Python code in one module gains access to the code in another module by the process of importing it.
意思就是说:Python 的模块太多啦,总不能把代码都写一块去吧?所以为了便于相互协作和后期维护,我们要把功能封装成模块,然后通过导入模块来复用代码。于是,我们就可以像上面的例子中 import keyword
来导入 keyword 模块,然后就可以访问模块中的函数和变量啦。
通常,模块有以下几种导入方式:
# 导入一个模块
import module_name
# 导入多个模块
import module_name1, module_name2
# 导入模块中的指定的属性、方法(不加括号)、类
from moudule_name import moudule_element [as new_name]
import 某一模块,相当于在当前环境中把某块内的代码执行一遍,使得该模块定义的变量、方法可见。为防止名称冲突,引用时通过 模块名.变量名(module.variable)的方式访问。如果在当前环境中还有同样名字的变量variable,它们俩之间是没有任何关系的,引用时要区分开。
“import module_name
” 的本质是将”module_name.py”中的全部代码加载到内存并赋值给与模块同名的变量写在当前文件中,这个变量的类型是 module。
如果代码中有多个地方需要重复调用同一个模块的同一个方法或变量,每次调用时, Python 都需要重复查找模块。所以可以使用”from module_name import module_element
“进行优化,减少了查找的过程。
另外,import 是具有层次性质的,即在当前模块中 import module_name
模块,那么,当前模块是不能访问 module_name 模块中 import 其他模块的对象的!
那么问题来了,模块从哪里导入?又能导入哪些模块呢?
Python 在模块导入的时候,默认先在当前目录下查找,然后再到系统中查找。系统查找的范围是 sys.path
下的所有路径,并且按顺序查找。
>>> import sys
>>> sys.path
['',
'/usr/lib/python35.zip',
'/usr/lib/python3.5',
'/usr/lib/python3.5/plat-x86_64-linux-gnu',
'/usr/lib/python3.5/lib-dynload',
'/usr/local/lib/python3.5/dist-packages',
'/usr/lib/python3/dist-packages']
执行sys.modules
可以列出 Python 启动时导入的模块,当某个模块第一次导入时,sys.modules 会自动记录该模块,后面再次导入该模块时,则直接查询 sys.modules,从而加快程序运行速度。实际上,sys.modules 是一个全局字典,因此可以使用字典所拥有的一切方法,比如 sys.modules.keys()
。
模块和包的区别
模块(module):用来从逻辑(实现一个功能)上组织 Python 代码(变量、函数、类),本质就是 *.py
文件。文件是物理上组织方式”module_name.py
“,模块是逻辑上组织方式”module_name
“。如果需要引用其他模块内的变量、方法或对象,在模块内还可以 import 进其他模块。
包(package):定义了一个由模块和子包组成的 Python 应用程序执行环境,本质就是一个有层次的文件目录结构(必须带有一个__init__.py
文件)。
我们可以通过 pip3 freeze
命令可以查看当前 Python 环境中已安装的包。
built-in 函数 & 库函数
内建模块(built-in modules)是 Python 解释器实现的模块(C 语言编写),它为 Python 程序直接提供操作接口,包括数据类型、文件 I/O 等常用的函数。如果没有这些 built-in 模块,Python 也将失去意义。实际上,内建函数也属于 Python 标准库的一部分。
内建函数都在 __builtins__
模块里面,在 Python 程序中,我们可以直接(global)使用它们,通过 “dir(__builtins__)
” 可以查看 Python 中的内建函数。
标准库(Standard Library)提供了很多 Python 编写的模块和函数,它们通常都是针对某一个特定的功能而设计的,比如 os、sys、time、datetime、math、urllib 模块等等。如果你使用的是 Windows 平台的 Python 环境,通常已经安装了完整的标准库和很多额外的软件包。不幸的是,如果你和我一样使用类 Unix 系统,那么通常只会安装 Python 解释器珍藏的那部分库,所以你还需要根据实际情况安装更多的软件包。
好消息是,有一个 PyPI(Python Package index)的网站收集了成千上万来自全球各地的 Python 模块。所以,我们推荐使用 pip 工具来安装相应的模块。比如使用如下命令安装 paho-mqtt 包:
pip3 install paho-mqtt
除了内建函数,其他函数(包括标准库和第三方模块)都需要 import 关键字导入模块才能使用。第三方模块一般安装在 dist-packages 或 site-packages 目录下。
【参考】