Photo by Chris Ried on Unsplash
Python 是一种易于学习又功能强大的编程语言。它提供了高效的高级数据结构,还有简单有效的面向对象编程。Python 优雅的语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的理想语言。
Python 解释器及丰富的标准库以源码或机器码的形式提供,可以到 Python 官网 www.python.org/ 免费获取适用于各个主要系统平台的版本,并可自由地分发。这个网站还包含许多免费第三方 Python 模块、程序和工具以及附加文档的发布页面或链接。
Python 解释器易于扩展,可以使用 C 或 C++(或者其他可以通过 C 调用的语言)扩展新的功能和数据类型。Python 也可用于可定制化软件中的扩展程序语言。
如果你经常在电脑上工作,总会有些任务会想让它自动化。比如,对一大堆文本文件进行查找替换,对很多照片文件按照比较复杂的规则重命名并放入不同的文件夹。也可能你想写一个小型的数据库应用,一个特定的界面应用,或者一个简单的游戏。
如果你是专业的软件开发人员,你可能需要编写一些 C/C++/Java 库,但总觉得通常的开发的流程(编写、编译、测试、再次编译等)太慢了。可能给这样的库写一组测试,就是很麻烦的工作了。或许你写了个软件,可以支持插件扩展语言,但你不想为了自己这一个应用,专门设计和实现一种新语言了。
那么,Python 正好能满足你的需要。
对于这些任务,你也可以写 Unix 脚本或者 Windows 批处理完成,但是 shell 脚本最擅长移动文件和替换文本,并不适合 GUI 界面或者游戏开发。你可以写一个 C/C++/Java 程序,但是可能第一版本的草稿都要很长的开发时间。Python 的使用则更加简单,可以在 Windows,Mac OS X,以及 Unix 操作系统上使用,而且可以帮你更快地完成工作。
Python 很容易使用,但它是一种真正的编程语言,提供了很多数据结构,也支持大型程序,远超 shell 脚本或批处理文件的功能。Python 还提供比 C 语言更多的错误检查,而且作为一种 “超高级语言”,它有高级的内置数据类型,比如灵活的数组和字典。正因为这些更加通用的数据类型,Python 能够应付更多的问题,超过 Awk 甚至 Perl,而且很多东西在 Python 中至少和那些语言同样简单。
Python 允许你划分程序模块,在其他的 Python 程序中重用。它内置了很多的标准模块,你可以在此基础上开发程序——也可以作为例子,开始学习 Python 编程。例如,文件输入输出,系统调用,套接字,甚至图形界面接口工作包比如 Tk 。
Python 是一种解释型语言,在程序开发阶段可以为你节省大量时间,因为不需要编译和链接。解释器可以交互式使用,这样就可以方便地尝试语言特性,写一些一次性的程序,或者在自底向上的程序开发中测试功能。它也是一个顺手的桌面计算器。
Python 程序的书写是紧凑而易读的。Python 代码通常比同样功能的 C,C++,Java 代码要短很多,原因列举如下:
Python 是 “可扩展的”:如果你知道怎么写 C 语言程序,就能很容易地给解释器添加新的内置函数或模块,不论是让关键的程序以最高速度运行,还是把 Python 程序链接到只提供预编译程序的库(比如硬件相关的图形库)。一旦你真正链接上了,就能在 Python 解释器中扩展或者控制 C 语言编写的应用了。
顺便提一下,这种语言的名字(Python 意为 “蟒蛇”)来自于 BBC 节目 “Monty Python 的飞行马戏团”,而与爬行动物没有关系。在文档中用 Monty Python 来开玩笑不只是可以的,还是推荐的!
现在你已经对 Python 跃跃欲试了,想要深入了解一些细节了。因为学习语言的最佳方式是使用它,本教程邀请你一边阅读,一边在 Python 解释器中玩耍。
在 Python 可用的机器上,Python 解释器通常放在 /usr/local/bin/python3.7 ; 把 /usr/local/bin 放到你 Unix shell 的搜索路径当中 , 这样就能键入命令:
python3.7复制代码
就能运行了。
安装时可以选择安装目录,所以解释器也可能在别的地方;可以问问你身边的 Python 大牛,或者你的系统管理员。(比如 /usr/local/python 也是比较常用的备选路径)
在 Windows 机器上, Python 安装通常放在 C:Python37 中,尽管你可以在运行安装程序时更改此设置。要将此目录添加到路径中,可以将以下命令键入 命令提示符窗口:
set path=%path%;C:python37复制代码
在主提示符中输入文件结束字符(在 Unix 系统中是 Control-D,Windows 系统中是 Control-Z)就退出解释器并返回退出状态为 0。如果这样不管用,你还可以写这个命令退出:quit()。
解释器的行编辑功能也包括交互式编辑,在支持 readline 的系统中,可以回看历史命令,也有 Tab 代码补全功能。要想快速检查是否支持行编辑,在出现提示符后,按键盘 Control-P。如果它 “哔” 了一声,它就是支持行编辑的;关于按键的详细介绍请看附录 交互式编辑和编辑历史。如果什么都没发生,或者显示出 ^P,那么就不支持行编辑功能;你只能用退格(Backspace)键从当前行中删除字符。
解释器运行的时候有点像 Unix 命令行:在一个标准输入 tty 设备上调用,它能交互式地读取和执行命令;调用时提供文件名参数,或者有个文件重定向到标准输入的话,它就会读取和执行文件中的 脚本。
另一种启动解释器的方式是 python -c command [arg] ...,其中 command 要换成想执行的指令,就像命令行的 -c 选项。由于 Python 代码中经常会包含对终端来说比较特殊的字符,通常情况下都建议用英文单引号把 command 括起来。
有些 Python 模块也可以作为脚本使用。可以这样输入:python -m module [arg] ...,这会执行 module 的源文件,就跟你在命令行把路径写全了一样。
在运行脚本的时候,有时可能也会需要在运行后进入交互模式。这种时候在文件参数前,加上选项 -i 就可以了。
关于所有的命令行选项,请参考 命令行与环境。
在终端(tty)输入并执行指令时,我们说解释器是运行在 交互模式(interactive mode)。在这种模式中,它会显示 主提示符(primary prompt),提示输入下一条指令,通常用三个大于号(>>>)表示;连续输入行的时候,它会显示 次要提示符,默认是三个点(...)。进入解释器时,它会先显示欢迎信息、版本信息、版权声明,然后就会出现提示符:
$ python3.7Python 3.7 (default, Sep 16 2015, 09:25:04)[GCC 4.8.2] on linuxType "help", "copyright", "credits" or "license" for more information.>>>复制代码
多行指令需要在连续的多行中输入。比如,以 if 为例:
>>> the_world_is_flat = True>>> if the_world_is_flat:... print("Be careful not to fall off!")...Be careful not to fall off!复制代码
有关交互模式的更多内容,请参考 交互模式。
默认情况下,Python 源码文件以 UTF-8 编码方式处理。在这种编码方式中,世界上大多数语言的字符都可以同时用于字符串字面值、变量或函数名称以及注释中——尽管标准库中只用常规的 ASCII 字符作为变量或函数名,而且任何可移植的代码都应该遵守此约定。要正确显示这些字符,你的编辑器必须能识别 UTF-8 编码,而且必须使用能支持打开的文件中所有字符的字体。
如果不使用默认编码,要声明文件所使用的编码,文件的 第一 行要写成特殊的注释。语法如下所示:
# -*- coding: encoding -*-复制代码
其中 encoding 可以是 Python 支持的任意一种 codecs。
比如,要声明使用 utf-8 编码,你的源码文件要写成:
# -*- coding: utf-8 -*-复制代码
关于 第一行 规则的一种例外情况是,源码以 UNIX "shebang" 行 开头。这种情况下,编码声明就要写在文件的第二行。例如:
#!/usr/bin/env python3# -*- coding: utf-8 -*-复制代码
Python 中的变量不需要提前声明。 变量赋值后会自动创建。
>>> width = 20>>> height = 5 * 9>>> width * height900复制代码
>>> 'spam eggs' # single quotes'spam eggs'>>> 'doesn't' # use ' to escape the single quote..."doesn't">>> "doesn't" # ...or use double quotes instead"doesn't">>> '"Yes," they said.''"Yes," they said.'>>> ""Yes," they said."'"Yes," they said.'>>> '"Isn't," they said.''"Isn't," they said.'复制代码
除了索引,字符串还支持 切片。索引可以得到单个字符,而 切片 可以获取子字符串:
>>> word[0:2] # characters from position 0 (included) to 2 (excluded)'Py'>>> word[2:5] # characters from position 2 (included) to 5 (excluded)'tho'复制代码
注意切片的开始总是被包括在结果中,而结束不被包括。这使得 s[:i] + s[i:] 总是等于 s
Python 中可以通过组合一些值得到多种 复合 数据类型,其中最常用的 列表。
>>> squares = [1, 4, 9, 16, 25]>>> squares[1, 4, 9, 16, 25]复制代码
>>> brother = ('小武', '小久', 2015, 2019)>>> numbers = (1, 2, 3, 4, 5 )>>> alpha = "a", "b", "c", "d">>> brother('小武', '小久', 2015, 2019)>>> numbers(1, 2, 3, 4, 5)>>> alpha('a', 'b', 'c', 'd')复制代码
mapping 对象会将 hashable 值映射到任意对象。 映射属于可变对象。 目前仅有一种标准映射类型 字典。
>>> a = dict(one=1, two=2, three=3)>>> b = {'one': 1, 'two': 2, 'three': 3}>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))>>> d = dict([('two', 2), ('one', 1), ('three', 3)])>>> e = dict({'three': 3, 'one': 1, 'two': 2})>>> a == b == c == d == eTrue复制代码
set 对象是由具有唯一性的 hashable 对象所组成的无序多项集。 常见的用途包括成员检测、从序列中去除重复项以及数学中的集合类计算。
无序的多项集
>>> basket = {'apple', 'orange', 'apple', 'grape', 'orange', 'banana'}>>> print(basket){'orange', 'banana', 'grape', 'apple'}>>> 'orange' in basketTrue>>> 'strawberry' in basketFalse复制代码
用于有条件的执行:
>>> x = int(input("Please enter an integer:"))Please enter an integer: 42>>> if x < 0:... x = 0... print('Negative changed to zero')... elif x == 0:... print('Zero')... elif x == 1:... print('Single')... else:... print('More')...More复制代码
可以有零个或多个 elif 部分,以及一个可选的 else 部分。 关键字 'elif' 是'else if' 的缩写,适合用于避免过多的缩进。 一个 if ... elif ... elif ... 序列可以看作是其他语言中的 switch 或 case 语句的替代。
用于对序列(例如字符串、元组或列表)或其他可迭代对象中的元素进行迭代:
>>> # Measure some strings:... words = ['cat', 'window', 'defenestrate']>>> for w in words:... print(w, len(w))...cat 3window 6defenestrate 12
用于在表达式保持为真的情况下重复地执行:
>>> monkeys = 5>>> while monkeys > 0:... print("{} 只猴子当荡秋千,嘲笑鳄鱼被水淹。鳄鱼来了,鳄鱼来了,啊呜!".format(monkeys))... monkeys -= 1...5 只猴子当荡秋千,嘲笑鳄鱼被水淹。鳄鱼来了,鳄鱼来了,啊呜!4 只猴子当荡秋千,嘲笑鳄鱼被水淹。鳄鱼来了,鳄鱼来了,啊呜!3 只猴子当荡秋千,嘲笑鳄鱼被水淹。鳄鱼来了,鳄鱼来了,啊呜!2 只猴子当荡秋千,嘲笑鳄鱼被水淹。鳄鱼来了,鳄鱼来了,啊呜!1 只猴子当荡秋千,嘲笑鳄鱼被水淹。鳄鱼来了,鳄鱼来了,啊呜!复制代码
break 语句,和 C 中的类似,用于跳出最近的 for 或 while 循环.
循环语句可能带有一个 else 子句;它会在循环遍历完列表 (使用 for) 或是在条件变为假 (使用 while) 的时候被执行,但是不会在循环被 break 语句终止时被执行。
>>> for n in range(2, 10):... for x in range(2, n):... if n % x == 0:... print(n, 'equals', x, '*', n//x)... break... else:... # loop fell through without finding a factor... print(n, 'is a prime number')...2 is a prime number3 is a prime number4 equals 2 * 25 is a prime number6 equals 2 * 37 is a prime number8 equals 2 * 49 equals 3 * 3复制代码
pass 语句什么也不做。当语法上需要一个语句,但程序需要什么动作也不做时,可以使用它。例如:
>>> while True:... pass # Busy-wait for keyboard interrupt (Ctrl+C)...复制代码
这通常用于创建最小的类:
>>> class MyEmptyClass:... pass...复制代码
pass 的另一个可以使用的场合是在你编写新的代码时作为一个函数或条件子句体的占位符,允许你保持在更抽象的层次上进行思考。 pass 会被静默地忽略:
>>> def initlog(*args):... pass # Remember to implement this!...复制代码
我们可以创建一个输出任意范围内 Fibonacci 数列的函数:
>>> def fib(n): # write Fibonacci series up to n... """Print a Fibonacci series up to n."""... a, b = 0, 1... while a < n:... print(a, end=' ')... a, b = b, a+b... print()...>>> # Now call the function we just defined:... fib(2000)0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597复制代码
现在你将要写更长,更复杂的 Python 代码,是时候讨论一下 代码风格。大多数语言都能使用不同的风格编写(或更简洁,格式化的);有些比其他的更具有可读性。能让其他人轻松阅读你的代码总是一个好主意,采用一种好的编码风格对此有很大帮助。
对于 Python,PEP 8 已经成为大多数项目所遵循的风格指南;它促进了一种非常易读且令人赏心悦目的编码风格。每个 Python 开发人员都应该在某个时候阅读它;以下是为你提取的最重要的几个要点:
>>> import thisThe Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!复制代码