Python简明教程

本文

主要介绍有关python的一些基础知识。

版本 说明
0.1 初版发布

背景

  • 主机: Thinkpad S2
  • 系统: Deepin GNU/Linux 15.11
  • 内核: Debian 6.3.0-18+deb9u1
  • python: Python 2.7.13

参考

写在前头

什么是Python?

Python语言是少有的一种可以称得上即简单又功能强大的编程语言。它具有以下特点:

  • 简单易学: 读Python程序就像是读英语,语法极其简单。
  • 免费开源: Python是FLOSS(自由/开放源码软件)之一。
  • 可移植: 多平台支持Python环境,方便程序移植。
  • 面向过程和面向对象: Python既支持面向过程,也支持面向对象。面向过程,由过程或仅仅是可重用代码的函数构建起来;面向对象,由数据和功能组合而成的对象构建起来。(个人理解,在当做脚本语言时,主要是面向过程编程)
  • 可扩展和可嵌入: Python程序可以使用其他语言,也可以被其他语言使用。
  • 丰富的函数库: Python标准库很大,功能很强。

安装Python

  • 如果你是Linux用户,系统应该已经自带Python,可以使用 python –version 查看版本号。如果没有安装(可能性很小),可以使用系统的包管理器安装 sudo apt install python ,或者去Python官网下载页面下载最新Linux版本,也可以从别人那里copy可执行二进制文件。
  • 如果你是windows用户,去Python官网下载页面下载最新Windows版本,手动安装,安装过程与其他软件类似,具体请自行百度。

运行方法

  • 可以在python解释器直接运行python命令,打开终端,在命令行键入python,启动解释器,现在输入print ‘Hello World’,然后按回车,会看到屏幕输出Hello World。
  • 使用源文件形式运行python程序: source HelloWorld.py
  • 可执行的Python程序: 将程序源文件更改为可执行属性 chmod 755 HelloWorld.py ,在终端命令行直接运行 ./HelloWorld.py

获取帮助

help() 函数用于查看函数或模块用途的详细说明,按q退出。(注意:查看模块前,需要先import模块)

>>>help('sys')             # 查看 sys 模块的帮助
……显示帮助信息……

>>>help('str')             # 查看 str 数据类型的帮助
……显示帮助信息……

>>>a = [1,2,3]
>>>help(a)                 # 查看列表 list 帮助信息
……显示帮助信息……

>>>help(re.findall)        # 显示re模块的findall方法的帮助
……显示帮助信息……

基本概念

  • 整数: 1、 2、 3、 -1、 -2、 -3(默认十进制,也可以采用其他进制表示: 0b 二进制,0o 八进制,0x 十六进制)
  • 浮点数: 3.14、 3.14E-4(也就是0.000314)
  • 复数: (-1+2j)、 (1-2j), 也可以complex(a,b)表示, 复数的实部 a 和虚部 b 都是浮点型

字符串

  • 单引号: ‘Hello \‘World!\'’,输出 Hello ‘World!’ (也就是单引号中使用单引号,需要转义,使用其他符号无需转义)
  • 双引号: “Hello \“World!\"",输出 Hello “World!” (也就是双引号中使用双引号,需要转义,使用其他符号无需转义)
  • 三引号(三个连续单引号): ‘‘‘‘Hello’ “World!"''',输出 ‘Hello’ “World!” (三引号中使用双引号和单引号,无需转义)
  • 转义符: 转义符是反斜杠 “\” ,如\\代表\符号,如‘Hello \‘World!\'’,\‘代表’(注意:行末的\,代表下一行继续,也就是不换行,而非转义符)
  • 自然字符串: 引号表示的一般字符串时是支持转义的,如果不需要转义,可以使用自然字符串(字符串前加r或R)。举例:一般字符串’hello \‘world\‘‘输出为hello ‘world’;自然字符串r’hello \‘world\‘‘输出为hello \‘world\’ 。
  • 自动拼接: print ‘Hello’ ‘World’ ,会输出 HelloWorld 。

变量

用标识符命名的存储单元的地址称为变量,变量是用来存储数据的,通过标识符可以获取变量的值,也可以对变量进行赋值。对变量赋值的意思是将值赋给变量,赋值完成后,变量所指向的存储单元存储了被赋的值,在Pyhton语言中赋值操作符为“=、+=、-=、*=、/=、%=、**=、//=”。声明变量的语法如: name=”Peter”

标识符

标识符用于Python语言的变量、关键字、函数、对象等数据的命名。标识符的命名需要遵循下面的规则。

  • 可以由字母(大写A—Z或小写a—z)、数字(0—9)和_(下划线)组合而成,但不能由数字开头;
  • 不能包含除_以外的任何特殊字符,如:%、#、&、逗号、空格等;
  • 不能包含空白字符(换行符、空格和制表符称为空白字符);
  • 标识符不能是Python语言的关键字和保留字;
  • 标识符区分大小写,num1和Num2是两个不同的标识符。
  • 标识符的命名要有意义,做到见名知意。

数据类型

Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。由于Python变量无需声明,所以它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。标准的数据类型由如下几个:

  • Number(数字)
  • String(字符串)
  • List(列表)
  • Tuple(元组)
  • Set(集合)
  • Dictionary(字典)

对象

python中一切皆为对象,一个对象的特征也称为属性(attribute)。它所具有的行为也称为方法(method) Python中的对象包含三要素:id、type、value 其中id用来唯一标识一个对象, type标识对象的类型, value是对象的值 is判断的是a对象是否就是b对象,是通过id来判断的 ==判断的是a对象的值是否和b对象的值相等,是通过value来判断的。

物理行和逻辑行

物理行是你在编写程序时所看见的。逻辑行是Python看见的单个语句。

  • 如果你想要在一个物理行中描述多个逻辑行,那么你需要在逻辑语句末尾添加”;",表示一个逻辑语句的结束(物理行末尾分号可写可不写)。
  • 如果你想要在多个物理行中描述一个逻辑行,那么你需要在物理行末添加”/",表示一个逻辑语句未结束,接下一行。

缩进

空白在Python中是重要的。事实上行首的空白是重要的。它称为缩进。在逻辑行首的空白(空格和制表符)用来决定逻辑行的缩进层次,从而用来决定语句的分组。也就是说,同一层次的语句必须有相同的缩进。

运算符

运算符

特别说明:运算符左右可以存在空格,也可以不存在空格,不同于shell中赋值符'=’,左右是不能有空格的。

  • 算数运算符:
运算符 名称 说明 例子
‘+’ 相加 3+5输出8; ‘a'+'b'输出’ab’
‘-’ 负数或相减 -5.2输出一个负数; 50-24输出26
‘*’ 相乘或字符串重复 2*3输出6; ‘la’*3输出’lalala’
‘**’ x的y次幂 3**4输出81(即3 * 3 * 3 * 3)
‘/’ x除以y 4/3输出1; 4.0/3或4/3.0输出1.3333333333333333;
’%‘ 取模 返回除法的余数 8%3输出2; -25.5%2.25输出1.5
‘//’ 取整 返回商的整数部分(向下取整) 5.9//2输出2.0
  • 比较运算符:
运算符 名称 说明 例子
‘<’ 小于 x是否小于y 是返回True,否返回False(首字母大写),5<3返回False; 3<5<7返回True
‘>’ 大于 x是否大于y 是返回True,否返回False(首字母大写),3>5返回False; 7>5>3返回True
‘<=’ 小于等于 x是否小于等于y x=3; y=6; x<=y返回True
‘>=’ 大于等于 x是否大于等于y x=4; y=3; x>=y返回True
‘==’ 等于 比较对象是否相等 x=2; y=2; x==y返回True; x='str’; y='stR’; x==y返回False
‘!='或'<>’ 不等于 比较两个对象是否不相等 x=2; y=3; x!=y返回True
  • 赋值运算符:
运算符 名称 说明
‘=’ 简单的赋值运算符 a=2+3, a结果为5
‘+=’ 加法赋值运算符 a=7, a+=2, a结果为9
‘-=’ 减法赋值运算符 a=7, a-=2, a结果为5
‘*=’ 乘法赋值运算符 a=7, a*=2, a结果为14
‘/=’ 除法赋值运算符 a=7, a/=2.0, a结果为3.5
‘%=’ 取模赋值运算符 a=7, a%=2, a结果为1
‘**=’ 幂赋值运算符 a=7, a**=2, a结果为49
‘//=’ 取整除赋值运算符 a=7, a//=2, a结果为3
  • 位运算符(避免表格中 或符号'|’ 被转义,这里使用 ‘竖线’ 代替):
运算符 名称 说明 例子
’«’ 左移 一个数的比特形式进行左移 2«2输出8,也就是0b10 «2 结果为0b1000
’»‘ 右移 一个数的比特形式进行右移 11»1输出5,也就是0b1011 »1 结果为ob101
’&’ 按位与 数的按位与 5&3输出1,也就是0b101 & 0b001 结果为0b001
‘竖线’ 按位或 数的按位或 5'竖线’3输出7,也就是0b101 ‘竖线’ 0b001 结果为0b111
‘^’ 按位异或 数的按位异或 5^1输出4,也就是0b101 ^ 0b001 结果为0b100
‘~’ 按位取反 x的按位取反,其值为-(x+1) ~5输出-6,也就是~0b0101 结果为0b1010(待补充)
  • 逻辑运算(符布尔与和或,建议表达式为判断表达式,而非计算表达式,除非你明确知道返回结果的形式是什么):
运算符 名称 说明 例子
‘not’ 布尔“非” not True 返回False x=2; y=3; not x!=y返回False
‘and’ 布尔“与” True and True 返回True 1<2 and 2<3 返回True; 1<2 and 2+3 返回2+3结果5
‘or’ 布尔“或” True or False 返回True 1<2 or 2>3 返回True; 1>2 or 2+3 返回2+3结果5
  • 成员运算符
运算符 说明
‘in’ 如果在指定的序列中找到值返回 True,否则返回 False。
‘not in’ 如果在指定的序列中没有找到值返回 True,否则返回 False。
  • 身份运算符
运算符 说明
‘is’ is 是判断两个标识符是不是引用自一个对象
‘is not’ is not 是判断两个标识符是不是引用自不同对象

是不是觉得is和==功能相同呢?那就理解错了,下面对is和==进一步说明。==是比较判断两个对象的value(值)是否相等;is比较判断两个对象id是否相同。举例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
>>> a = 1 #a和b为数值类型
>>> b = 1
>>> a is b
True
>>> id(a)
14318944
>>> id(b)
14318944
>>> a = 'cheesezh' #a和b为字符串类型
>>> b = 'cheesezh'
>>> a is b
True
>>> id(a)
42111872
>>> id(b)
42111872
>>> a = (1,2,3) #a和b为元组类型
>>> b = (1,2,3)
>>> a is b
False
>>> id(a)
15001280
>>> id(b)
14790408
>>> a = [1,2,3] #a和b为list类型
>>> b = [1,2,3]
>>> a is b
False
>>> id(a)
42091624
>>> id(b)
42082016
>>> a = {'cheese':1,'zh':2} #a和b为dict类型
>>> b = {'cheese':1,'zh':2}
>>> a is b
False
>>> id(a)
42101616
>>> id(b)
42098736
>>> a = set([1,2,3])#a和b为set类型
>>> b = set([1,2,3])
>>> a is b
False
>>> id(a)
14819976
>>> id(b)
14822256

总结:只有数值型和字符串型的情况下,a is b才为True,当a和b是tuple,list,dict或set型时,a is b为False。

运算符优先级

优先级从高到低。

运算符 说明
** 指数 (最高优先级)
~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
* / % // 乘,除,求余数和取整除
+ - 加法减法
» « 右移,左移运算符
& 位 ‘AND’
^ ‘竖线’ 位运算符
<= < > >= 比较运算符
== 等于运算符
= %= /= //= -= += *= **= 赋值运算符
is is not 身份运算符
in not in 成员运算符
not and or 逻辑运算符

虽然python解释器对运算符号优先级指明了顺序,但还是建议使用圆括号来更明确地指出运算的先后顺序,使程序尽可能地易读。例如,2+(3*4)显然比2+3*4清晰。

控制流

if判断

Python程序语言指定任何非0和非空(null)值为true,0 或者 null为false。条件判断语句中,“判断条件"成立时(非零),则执行后面的语句,执行内容可以多行,以缩进来区分表示同一范围。其中else 为可选语句,当需要在条件不成立时执行内容则可以执行相关语句。举例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
num = 5
if num == 3:            # 判断num的值
    print 'boss1'
    print 'boss2'
    print 'boss3'
elif num < 0:           # 值小于零时输出
    print 'worker1'
    print 'worker2'
    print 'worker3'
else:                   # 条件均不成立时输出
    print 'roadman1'
    print 'roadman2'
    print 'roadman3'

输出结果为:

roadman1
roadman2
roadman3

while循环

while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。while语句有一个可选的else从句,在不满足while条件时执行。举例如下:

1
2
3
4
5
6
7
8
count = 0
while (count < 3):
   print 'The count is:', count
   count = count + 1
else:
   print "end while at count:", count

print "Good bye!"

结果如下:

The count is: 0
The count is: 1
The count is: 2
end while at count: 3
Good bye!

for循环

Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串。for语句有一个可选的else从句,在执行完for内容时执行一次(除非遇到break)。举例如下:

1
2
3
4
5
6
7
8
for i in [1,2,3]:
   print i
else:
   print 'end for i=', i

#------------------------
for letter in 'ABC':
   print 'letter:', letter

结果如下:

1
2
3
end for i= 3
letter: A
letter: B
letter: C

break语句

break语句可以强制终止循环语句,即使while循环条件仍为True或for循环序列还没有被完全递归。注意:break终止for或while循环 ,对应的循环else块将不执行。举例如下:

1
2
3
4
5
6
7
8
9
i = 1
while i<5:
    print i
    i += 1
    if i > 3:
        break
        print 'there is break'
else:
    print 'end while, i=', i

结果如下(可以去除break语句,将结果进行比较):

1
2
3

continue语句

continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后 继续 进行下一轮循环。举例如下:

1
2
3
4
5
6
7
8
9
i = 1
while i<5:
    print i
    i += 1
    if i > 3:
        continue
        print 'there is continue'
else:
    print 'end while, i=', i

结果如下(可以去除continue语句,将结果进行比较):

1
2
3
4
end while, i= 5

函数

函数通过def关键字定义。def关键字后跟一个函数的 标识符 名称,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。

函数形参

函数取得的参数是你提供给函数的值,这样函数就可以利用这些值 做 一些事情。这些参数就像变量一样,只不过它们的值是在我们调用函数的时候定义的,而非在函数本身内赋值。参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。注意我们使用过的术语——函数中的参数名称为 形参 而你提供给函数调用的值称为实参。举例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
def printMax(a, b):
    if a > b:
         print a, 'is maximum'
    else:
         print b, 'is maximum'

#----------------------------------------------

printMax(3, 4) # directly give literal values

x = 5
y = 7
printMax(x, y) # give variables as arguments

结果如下:

4 is maximum
7 is maximum

局部变量

在函数内声明的变量,与函数外具有相同名称的其他变量没有任何关系,也就是变量的作用域仅限于函数内容,是局部的,这样的变量被称作局部变量。举例如下(注意,函数要先定义,才可以使用):

1
2
3
4
5
6
7
def local_test(num):
    num += num
    print 'local_test\'s num is', num

num = 10
local_test(num)
print 'main_program\'s num is', num

结果如下:

local_test's num is 20
main_program's num is 10

默认参数

对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。注意:不能先声明有默认值的形参而后声明没有默认值的形参。如 def func(a, b=5, c=3) 是有效的, def func(a=5, b) 是无效的。举例如下:

1
2
3
4
5
def say(message, times = 1):
    print message * times

say('Hello')
say('World', 3)

结果如下:

Hello
WorldWorldWorld

关键字参数

如果某个函数有许多参数,只想指定其中某些参数的值,可以通过命名来为这些参数赋值,这种方法就是关键字参数。换句话说,关键字参数就是调用参数时使用名字(关键字)而不是位置来给函数指定实参。举例如下:

1
2
3
4
5
6
def func(a, b=5, c=10):
    print 'a =', a
    print 'b =', b
    print 'c =', c

func(c=1, b=2, a=3)

结果如下:

a = 3
b = 2
c = 1

return语句

return 语句就是讲结果返回到调用的地方,并把程序的控制权一起返回程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return。举例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def add_sub (a, b):
    c = a + b
    d = a - b
    return c, d

x = 3
y = 2
m, n = add_sub(x,y)

print x, '+', y, '=', m
print x, '-', y, '=', n

结果如下:

3 + 2 = 5
3 - 2 = 1

文档字符串

DocStrings 文档字符串是一个重要工具,用于解释文档程序,帮助你的程序文档更加简单易懂。我们可以在函数体的第一行使用一对三个单引号 '’’ 或者一对三个双引号 "”” 来定义文档字符串。你可以使用 __doc__(注意双下划线)调用函数中的文档字符串属性。举例如下:

1
2
3
4
5
6
def function():
    ''' The introduction to function.
    '''
    pass

print (function.__doc__)

输出结果如下:

The introduction to function.

特别说明:在函数的第一个逻辑行的字符串是这个函数的文档字符串(也适用于模块和类)。文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾,一般概括介绍函数的功能。第二行是空行,从第三行开始是详细介绍函数功能和使用方法。强烈建议,函数中使用文档字符串时遵循这个惯例。

模块

什么是模块?

在python中,一个文件(以“.py”为后缀名的文件)就叫做一个模块,每一个模块在python里都被看做是一个独立的文件。模块可以被其他程序引用,从而使用该模块里的函数等功能,使用Python中的标准库也是采用这种方法。

Python中模块分为以下三类:

  • 系统内置模块:如:sys、time、json模块等等;
  • 自定义模块:自定义模块是自己写的模块,对某段逻辑或某些函数进行封装后供其他函数调用;
  • 第三方的开源模块:这部分模块可以通过pip install进行安装,有开源的代码;

import模块

首先模块要先使用import语句导入到程序,如“import sys”导入sys模块,import的使用遵循以下规则:

  • 使用关键词“import”,后面跟具体的模块名称,则可以导入某一个模块;
  • 同一个模块不管你执行了多少次“import”,只会被导入一次,以防止模块一遍又一遍的被执行;
  • “import”应该被放在代码的顶端;

再来你说一说import的搜索路径和顺序,如下:

  1. 当前目录
  2. 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
  3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。

如果我们自定义一个模块(不能与系统模块重名),如何让python成功import呢?第一,我们可以将模块文件与引用模块的程序放在同一目录,可自动搜索到;第二,修改系统环境变量PYTHONPATH,比如自定义模板文件放在~/my_lib,可以将以下内容添加到~/.bashrc,并重启终端。

1
export PYTHONPATH=~/my_lib/:$PYTHONPATH

from…import 语句

Python 的 from 语句可以从模块中导入一个指定的部分到当前命名空间中。举例如下:

1
from fib import fibonacci

也可以使用import modname from *语句,将模块中所有函数导入到当前命名空间中,但不建议这样做。举例如下:

1
from fib import *

import和import…from的区别

import和import…from的区别,从函数引用来看就理解了,如下(support是自定义的模块,只为解释模块使用):

  • import
1
2
import support
support.print_func("Runoob")
  • import…from
1
2
from support import *
print_func("Runoob")

从以上内容也看出,import和import…from的区别,也知道为什么不建议使用import…from * ,因为这样有可能带来函数命名上的冲突。总之,建议还是直接使用import。

python中的包

包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。简单来说,包就是文件夹,但该文件夹下必须存在__init__.py 文件, 该文件的内容可以为空。__init__.py 用于标识当前文件夹是一个包。

如定义一个包,文件目录如下:

package_runoob
|-- __init__.py
|-- runoob1.py
|-- runoob2.py

使用程序:

1
2
from package_runoob.runoob1 import runoob1
from package_runoob.runoob2 import runoob2

python的标准库

python的标准库内容很多,这也是Python强大之处,在这里不进行描述,后续会根据自己使用情况,对某些內建函数进行介绍。分享一个Python标准库介绍文档,可供查阅,百度网盘分享资源: 链接:https://pan.baidu.com/s/1o7G32%5FilSHhflfYTHuJq3g 密码:h2vv

数据结构

在Python中有三种内建的数据结构——列表、元组和字典。我们将会学习如何使用它们,以及它们如何使编程变得简单。

列表

列表中的元素应该包括在方括号中,并用逗号隔开。列表中,可以添加、删除或是搜索列表中的元素。由于可以增加或删除元素,所以列表是可变的数据类型。列表中的每个元素都分配一个数字(用来索引它的位置),第一个索引是0,第二个索引是1,依此类推。创建列表的方法如下:

1
2
3
list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]

访问列表中的值(列表索引时,默认从左到右,负号‘-’可代表从右到左,冒号‘:’可定义区间,省略则代表起始或末尾):

1
2
3
4
5
6
7
list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5, 6, 7 ]

print "list1[0]: ", list1[0]
print "list1[-2]: ", list1[-2]
print "list2[1:5]: ", list2[1:5]
print "list2[1:]: ", list2[1:]

添加、修改和删除列表中的元素:

1
2
3
4
list = []               ## 创建空列表
list.append('Google')   ## 在列表末尾添加元素
list[0] = 'Baidu'       ## 修改列表第一个元素
del list[0]             ## 删除列表中第一个元素

列表的操作符:

表达式 结果 说明
len([1, 2, 3]) 3 长度
[1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] 组合
[‘Hi!'] * 4 [‘Hi!', ‘Hi!', ‘Hi!', ‘Hi!'] 重复
3 in [1, 2, 3] True 元素是否存在于列表中
for x in [1, 2, 3]: print x 1 2 3 迭代

Python列表函数:

函数 说明
len(list) 列表元素个数
max(list) 返回列表元素最大值
min(list) 返回列表元素最小值
list(seq) 将元组转换为列表

Python列表方法:

方法 说明
list.append(obj) 在列表末尾添加新的对象
list.count(obj) 统计某个元素在列表中出现的次数
list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
list.insert(index, obj) 将对象插入列表
list.pop(obj=list[-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
list.remove(obj) 移除列表中某个值的第一个匹配项
list.reverse() 反向列表中元素
list.sort([func]) 对原列表进行排序

元组

Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可(元组中只包含一个元素时,需要在元素后面添加逗号)。如下:

1
2
3
4
5
tup1 = ('physics', 'chemistry', 1997, 2000)
tup2 = (1, 2, 3, 4, 5 )
tup3 = "a", "b", "c", "d"
tup4 = ()
tup5 = (33,)

元组的运算和索引与列表相同,可参考列表。唯一不同的是元组不可修改,不可删除,不可添加。

元组的函数:

方法 说明
cmp(tuple1, tuple2) 比较两个元组元素
len(tuple) 计算元组元素个数
max(tuple) 返回元组中元素最大值
min(tuple) 返回元组中元素最小值
tuple(seq) 将列表转换为元组

字典

字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中,举例如下:

1
2
3
4
5
dict = {
    'Alice': '2341',
    'Beth': '9102',
    'Cecil': '3258'
}

多级字典嵌套:

1
2
3
4
5
dict = {
    'Alice': {'Height': 168, 'Weight': 96},
    'Beth': {'Height': 173, 'Weight': 126},
    'Cecil': {'Height': 185, 'Weight': 148}
}

访问字典数据(如果key不存在,则会报告异常):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
dict = {
    'Alice': '2341',
    'Beth': '9102',
    'Cecil': '3258'
}

print "dict['Alice']: ", dict['Alice']

#------------------------------------------

dict = {
    'Alice': {'Height': 168, 'Weight': 96},
    'Beth': {'Height': 173, 'Weight': 126},
    'Cecil': {'Height': 185, 'Weight': 148}
}

print "dict['Alice']['Height']: ", dict['Alice']['Height']

修改、删除和添加字典元素:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

dict['Age'] = 8 # update
dict['School'] = "RUNOOB" #add

print "dict['Age']: ", dict['Age']
print "dict['School']: ", dict['School']

del dict['Name']  # delete Name
dict.clear()      # clear dict
del dict          # delete dict

字典的特性:

  • 不允许同一个key出现两次。创建时如果同一个key被赋值两次,后一个会覆盖前一个。
  • key必须不可变,所以可以用数字,字符串或元组充当,而用列表就不行。

字典内置函数:

序号 说明
cmp(dict1, dict2) 比较两个字典元素
len(dict) 计算字典元素个数,即key的总数
str(dict) 输出字典可打印的字符串表示
type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型

字典内置方法:

序号 说明
dict.clear() 删除字典内所有元
dict.copy() 返回一个字典的浅复
dict.fromkeys(seq[, val]) 创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始
dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回default
dict.has_key(key) 如果键在字典dict里返回true,否则返回fals
dict.items() 以列表返回可遍历的(键, 值) 元组数
dict.keys() 以列表返回一个字典所有的
dict.setdefault(key, default=None) 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为defaul
dict.update(dict2) 把字典dict2的键/值对更新到dict
dict.values() 以列表返回字典中的所有
pop(key[,default]) 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值
popitem() 返回并删除字典中的最后一对键和值

序列

列表、元组和字符串都是序列,但是序列是什么,它们为什么如此特别呢?序列的两个主要特点是索引操作符和切片操作符。索引操作符让我们可以从序列中抓取一个特定项目。切片操作符让我们能够获取序列的一个切片,即一部分序列。索引和切片的使用方法在列表和元组中已经有介绍,这里不再赘述。

引用

创建一个对象并给它赋一个变量的时候,这个变量仅仅 引用 那个对象,而不是表示这个对象本身!j简单来说,创建的对象指向的是计算机中存储赋值对象的内存,而并非重新开辟一块内存对应被赋值对象。一般说来,使用者不需要关心,但是如果你想要复制一个列表或者类似的序列,必须使用切片操作符来取得拷贝,如果只是想要使用另一个变量名,可以直接赋值,不过两个名称都引用同一个对象,一不小心就可能会引来各种麻烦。特别给Perl程序员提示:python中序列的赋值语句不创建拷贝,需要使用切片操作符来建立序列的拷贝。举例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
print 'Simple Assignment'
shoplist = ['apple', 'mango', 'carrot', 'banana']
mylist = shoplist # mylist is just another name pointing to the same object!
del shoplist[0]
print 'shoplist is', shoplist
print 'mylist is', mylist
# notice that both shoplist and mylist both print the same list without
# the 'apple' confirming that they point to the same object

#---------------------------------------------------------------------

print 'Copy by making a full slice'
mylist = shoplist[:] # make a copy by doing a full slice
del mylist[0] # remove first item
print 'shoplist is', shoplist
print 'mylist is', mylist
# notice that now the two lists are different

中文

Python中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字,所以在读取中文时会报错。解决方法为只要在文件开头加入 # -- coding: UTF-8 -- 或者 # coding=utf-8 就行了。注意: # coding=utf-8 的 = 号两边不要空格。如果以上教程中出现中文注释或其他中文内容,运行时报错,请添加中文支持。

输入输出

打印的屏幕

最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式(显示时,Python会在逗号分隔处自动插入一个空格)。此函数把你传递的表达式转换成一个字符串表达式,并将结果写到标准输出如下:

1
print "Python","是一个非常棒的语言,不是吗?"

读取键盘输入

raw_input函数,raw_input([prompt]) 函数从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符):

1
2
str = raw_input("请输入:")
print "你输入的内容是: ", str

input函数,input([prompt]) 函数和 raw_input([prompt]) 函数基本类似,但是 input 可以接收一个Python表达式作为输入,并将运算结果返回。

1
2
str = input("请输入:")
print "你输入的内容是: ", str

举例如下(input):

  请输入:[x*5 for x in range(2,10,2)]
  你输入的内容是:  [10, 20, 30, 40]

文件操作

打开文件

语法规则如下:

1
file object = open(file_name [, access_mode][, buffering])

参数说明:

  • file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
  • access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
  • buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。

模式说明:

模式 说明
t 文本模式 (默认)
b 二进制模式
x 写模式,新建一个文件,如果该文件已存在则会报错
+ 打开一个文件进行更新可读可写
r 以只读方式打开文件(默认模式)
r+ 打开一个文件用于读写
w 打开一个文件只用于写入(文件存在则覆盖,不存在则新建)
w+ 打开一个文件只用于读写(文件存在则覆盖,不存在则新建)
a 打开一个文件用于追加(文件存在则末尾添加内容,不存在则新建))
a+ 打开一个文件用于读写(文件存在则末尾添加内容,不存在则新建))

对r+、w+、a+进一步说明:

描述 r+ w+ a+
当前文件不存在时文件 抛出异常 创建文件 创建文件
打开后原文件内容 保留 清空 保留
初始位置 0 0 文件尾
写入位置 标记位置 标记位置 写入时默认跳至文件尾

文件对象属性

属性 描述
file.closed 返回true如果文件已被关闭,否则返回false
file.mode 返回被打开文件的访问模式
file.name 返回文件的名称
file.softspace 如果用print输出后,必须跟一个空格符,则返回false。否则返回true

关闭文件

File 对象的 close()方法刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。用 close()方法关闭文件是一个很好的习惯。语法:

1
fileObject.close()

write和read

write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。write()方法不会在字符串的结尾添加换行符('\n’),举例如下,创建foo.txt文件,并将内容写入该文件,并最终关闭文件:

1
2
3
4
5
6
# 打开一个文件
fo = open("foo.txt", "w")
fo.write( "www.runoob.com!\nVery good site!\n")

# 关闭打开的文件
fo.close()

read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。 read需要传入一个参数,被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。举例如下(读取上面创建的文件前10个字符):

1
2
3
4
5
6
# 打开一个文件
fo = open("foo.txt", "r+")
str = fo.read(10)
print "读取的字符串是 : ", str
# 关闭打开的文件
fo.close()

文件定位

tell()方法告诉你文件内的当前位置, 换句话说,下一次的读写会发生在文件开头这么多字节之后。seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。 举例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 打开一个文件
fo = open("foo.txt", "r+")
str = fo.read(10)
print "读取的字符串是 : ", str

# 查找当前位置
position = fo.tell()
print "当前文件位置 : ", position

# 把指针再次重新定位到文件开头
position = fo.seek(0, 0)
str = fo.read(10)
print "重新读取字符串 : ", str
# 关闭打开的文件
fo.close()

os模块

Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。要使用这个模块,你必须先导入它,然后才可以调用相关的各种功能,通过import导入模块可参考上文模块章节。

  • rename:
1
2
# 重命名文件test1.txt到test2.txt。
os.rename( "test1.txt", "test2.txt" )
  • remove:
1
2
# 删除一个已经存在的文件test2.txt
os.remove("test2.txt")
  • mkdir:
1
2
# 创建目录test
os.mkdir("test")
  • chdir:
1
2
# 将当前目录改为"/home/newdir"
os.chdir("/home/newdir")
  • getcwd:
1
2
# 给出当前的目录
print os.getcwd()
  • 其他,可参考os模块提供的内建函数手册。

异常处理

什么是异常?

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。一般情况下,在python无法正常处理程序时就会发生一个异常(异常是python对象,表示一个错误)。错误分两种:

  • 语法错误: 这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正。
  • 逻辑错误: 程序执行时遇到的错误,比如0做除数。

异常种类有哪些?

常见的异常种类:

异常类型 说明
AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的

所有标准异常

异常类型 说明
BaseException 所有异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(通常是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
SystemExit Python 解释器请求退出
StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (所有数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
KeyboardInterrupt 用户中断执行(通常是输入^C)
LookupError 无效数据查询的基类
IndexError 序列中没有没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
NameError 未声明/初始化对象 (没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 一般的解释器系统错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告

异常处理的方法

  • 如果错误发生的条件是可预知的,我们需要用if进行处理,在错误发生之前进行预防。
1
2
3
4
5
6
7
8
AGE=10
while True:
    age=input('>>: ').strip()
    if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
        age=int(age)
        if age == AGE:
            print('you got it')
            break
  • 如果错误发生的条件是不可预知的,则需要用到try..except:在错误发生之后进行处理。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
try:
    f=open('a.txt')
    g=(line.strip() for line in f)
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
except StopIteration:
    f.close()

try…except…的详细用法

我们把可能发生错误的语句放在try模块里,用except来处理异常。except可以处理一个专门的异常,也可以处理一组圆括号中的异常,如果except后没有指定异常,则默认处理所有的异常。每一个try,都必须至少有一个except。

  • 异常类只能来处理指定的异常情况,如果非指定异常则无法处理:
1
2
3
4
5
s1 = 'hello'
try:
    int(s1)
except IndexError as e: # 未捕获到异常,程序直接报错
    print e
  • 多分支:
1
2
3
4
5
6
7
8
9
s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
  • 多分支+Exception:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)
  • 异常的其他机构(try…finally语法):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
#except Exception as e:
#    print(e)
else:
    print('try内代码块没有异常则执行我')
finally:
    print('无论异常与否,都会执行该模块,通常是进行清理工作')
  • 主动触发异常(raise语句):
1
2
3
4
def functionName( level ):
    if level < 1:
        raise Exception("Invalid level!", level)
        # 触发异常后,后面的代码就不会再执行
  • 自定义异常:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Networkerror(BaseException):
    def __init__(self,msg):
        self.msg=msg
    def __str__(self):
        return self.msg

try:
    raise Networkerror('类型错误')
except Networkerror as e:
    print(e)
  • 断言:assert条件:
1
2
assert 1 == 1
assert 1 == 2

总结: 使用异常处理方法,可以时代码程序拥有以下几个优点, 1)把错误处理和真正的工作分开来; 2)代码更易组织,更清晰,复杂的工作任务更容易实现; 3)代码更成熟,不至于由于一些小的疏忽而使程序意外崩溃了。 既然异常处理有这么多好处,是不是要为每一段程序都加上try…except呢?首先try…except是附加的一种异常处理逻辑,与主要的工作是没有关系的,这种东西加的多了,会导致代码可读性变差,其次只有在错误发生的条件无法预知的情况下,才应该做异常处理,而不是为自己不成熟的代码擦屁股。