本文
主要介绍有关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是否相同。举例如下:
|
|
总结:只有数值型和字符串型的情况下,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 为可选语句,当需要在条件不成立时执行内容则可以执行相关语句。举例如下:
|
|
输出结果为:
roadman1
roadman2
roadman3
while循环
while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。while语句有一个可选的else从句,在不满足while条件时执行。举例如下:
|
|
结果如下:
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
end for i= 3
letter: A
letter: B
letter: C
break语句
break语句可以强制终止循环语句,即使while循环条件仍为True或for循环序列还没有被完全递归。注意:break终止for或while循环 ,对应的循环else块将不执行。举例如下:
|
|
结果如下(可以去除break语句,将结果进行比较):
1
2
3
continue语句
continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后 继续 进行下一轮循环。举例如下:
|
|
结果如下(可以去除continue语句,将结果进行比较):
1
2
3
4
end while, i= 5
函数
函数通过def关键字定义。def关键字后跟一个函数的 标识符 名称,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。
函数形参
函数取得的参数是你提供给函数的值,这样函数就可以利用这些值 做 一些事情。这些参数就像变量一样,只不过它们的值是在我们调用函数的时候定义的,而非在函数本身内赋值。参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。注意我们使用过的术语——函数中的参数名称为 形参 而你提供给函数调用的值称为实参。举例如下:
|
|
结果如下:
4 is maximum
7 is maximum
局部变量
在函数内声明的变量,与函数外具有相同名称的其他变量没有任何关系,也就是变量的作用域仅限于函数内容,是局部的,这样的变量被称作局部变量。举例如下(注意,函数要先定义,才可以使用):
|
|
结果如下:
local_test's num is 20
main_program's num is 10
默认参数
对于一些函数,你可能希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。注意:不能先声明有默认值的形参而后声明没有默认值的形参。如 def func(a, b=5, c=3) 是有效的, def func(a=5, b) 是无效的。举例如下:
|
|
结果如下:
Hello
WorldWorldWorld
关键字参数
如果某个函数有许多参数,只想指定其中某些参数的值,可以通过命名来为这些参数赋值,这种方法就是关键字参数。换句话说,关键字参数就是调用参数时使用名字(关键字)而不是位置来给函数指定实参。举例如下:
|
|
结果如下:
a = 3
b = 2
c = 1
return语句
return 语句就是讲结果返回到调用的地方,并把程序的控制权一起返回程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return。举例如下:
|
|
结果如下:
3 + 2 = 5
3 - 2 = 1
文档字符串
DocStrings 文档字符串是一个重要工具,用于解释文档程序,帮助你的程序文档更加简单易懂。我们可以在函数体的第一行使用一对三个单引号 '’’ 或者一对三个双引号 "”” 来定义文档字符串。你可以使用 __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的搜索路径和顺序,如下:
- 当前目录
- 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
如果我们自定义一个模块(不能与系统模块重名),如何让python成功import呢?第一,我们可以将模块文件与引用模块的程序放在同一目录,可自动搜索到;第二,修改系统环境变量PYTHONPATH,比如自定义模板文件放在~/my_lib,可以将以下内容添加到~/.bashrc,并重启终端。
|
|
from…import 语句
Python 的 from 语句可以从模块中导入一个指定的部分到当前命名空间中。举例如下:
|
|
也可以使用import modname from *语句,将模块中所有函数导入到当前命名空间中,但不建议这样做。举例如下:
|
|
import和import…from的区别
import和import…from的区别,从函数引用来看就理解了,如下(support是自定义的模块,只为解释模块使用):
- import
|
|
- import…from
|
|
从以上内容也看出,import和import…from的区别,也知道为什么不建议使用import…from * ,因为这样有可能带来函数命名上的冲突。总之,建议还是直接使用import。
python中的包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。简单来说,包就是文件夹,但该文件夹下必须存在__init__.py 文件, 该文件的内容可以为空。__init__.py 用于标识当前文件夹是一个包。
如定义一个包,文件目录如下:
package_runoob
|-- __init__.py
|-- runoob1.py
|-- runoob2.py
使用程序:
|
|
python的标准库
python的标准库内容很多,这也是Python强大之处,在这里不进行描述,后续会根据自己使用情况,对某些內建函数进行介绍。分享一个Python标准库介绍文档,可供查阅,百度网盘分享资源: 链接:https://pan.baidu.com/s/1o7G32%5FilSHhflfYTHuJq3g 密码:h2vv 。
数据结构
在Python中有三种内建的数据结构——列表、元组和字典。我们将会学习如何使用它们,以及它们如何使编程变得简单。
列表
列表中的元素应该包括在方括号中,并用逗号隔开。列表中,可以添加、删除或是搜索列表中的元素。由于可以增加或删除元素,所以列表是可变的数据类型。列表中的每个元素都分配一个数字(用来索引它的位置),第一个索引是0,第二个索引是1,依此类推。创建列表的方法如下:
|
|
访问列表中的值(列表索引时,默认从左到右,负号‘-’可代表从右到左,冒号‘:’可定义区间,省略则代表起始或末尾):
|
|
添加、修改和删除列表中的元素:
|
|
列表的操作符:
表达式 | 结果 | 说明 |
---|---|---|
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的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可(元组中只包含一个元素时,需要在元素后面添加逗号)。如下:
|
|
元组的运算和索引与列表相同,可参考列表。唯一不同的是元组不可修改,不可删除,不可添加。
元组的函数:
方法 | 说明 |
---|---|
cmp(tuple1, tuple2) | 比较两个元组元素 |
len(tuple) | 计算元组元素个数 |
max(tuple) | 返回元组中元素最大值 |
min(tuple) | 返回元组中元素最小值 |
tuple(seq) | 将列表转换为元组 |
字典
字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中,举例如下:
|
|
多级字典嵌套:
|
|
访问字典数据(如果key不存在,则会报告异常):
|
|
修改、删除和添加字典元素:
|
|
字典的特性:
- 不允许同一个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中序列的赋值语句不创建拷贝,需要使用切片操作符来建立序列的拷贝。举例如下:
|
|
中文
Python中默认的编码格式是 ASCII 格式,在没修改编码格式时无法正确打印汉字,所以在读取中文时会报错。解决方法为只要在文件开头加入 # -- coding: UTF-8 -- 或者 # coding=utf-8 就行了。注意: # coding=utf-8 的 = 号两边不要空格。如果以上教程中出现中文注释或其他中文内容,运行时报错,请添加中文支持。
输入输出
打印的屏幕
最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式(显示时,Python会在逗号分隔处自动插入一个空格)。此函数把你传递的表达式转换成一个字符串表达式,并将结果写到标准输出如下:
|
|
读取键盘输入
raw_input函数,raw_input([prompt]) 函数从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符):
|
|
input函数,input([prompt]) 函数和 raw_input([prompt]) 函数基本类似,但是 input 可以接收一个Python表达式作为输入,并将运算结果返回。
|
|
举例如下(input):
请输入:[x*5 for x in range(2,10,2)]
你输入的内容是: [10, 20, 30, 40]
文件操作
打开文件
语法规则如下:
|
|
参数说明:
- 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()方法关闭文件是一个很好的习惯。语法:
|
|
write和read
write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。write()方法不会在字符串的结尾添加换行符('\n’),举例如下,创建foo.txt文件,并将内容写入该文件,并最终关闭文件:
|
|
read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。 read需要传入一个参数,被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。举例如下(读取上面创建的文件前10个字符):
|
|
文件定位
tell()方法告诉你文件内的当前位置, 换句话说,下一次的读写会发生在文件开头这么多字节之后。seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。 举例如下:
|
|
os模块
Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。要使用这个模块,你必须先导入它,然后才可以调用相关的各种功能,通过import导入模块可参考上文模块章节。
- rename:
|
|
- remove:
|
|
- mkdir:
|
|
- chdir:
|
|
- 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进行处理,在错误发生之前进行预防。
|
|
- 如果错误发生的条件是不可预知的,则需要用到try..except:在错误发生之后进行处理。
|
|
try…except…的详细用法
我们把可能发生错误的语句放在try模块里,用except来处理异常。except可以处理一个专门的异常,也可以处理一组圆括号中的异常,如果except后没有指定异常,则默认处理所有的异常。每一个try,都必须至少有一个except。
- 异常类只能来处理指定的异常情况,如果非指定异常则无法处理:
|
|
- 多分支:
|
|
- 多分支+Exception:
|
|
- 异常的其他机构(try…finally语法):
|
|
- 主动触发异常(raise语句):
|
|
- 自定义异常:
|
|
- 断言:assert条件:
|
|
总结: 使用异常处理方法,可以时代码程序拥有以下几个优点, 1)把错误处理和真正的工作分开来; 2)代码更易组织,更清晰,复杂的工作任务更容易实现; 3)代码更成熟,不至于由于一些小的疏忽而使程序意外崩溃了。 既然异常处理有这么多好处,是不是要为每一段程序都加上try…except呢?首先try…except是附加的一种异常处理逻辑,与主要的工作是没有关系的,这种东西加的多了,会导致代码可读性变差,其次只有在错误发生的条件无法预知的情况下,才应该做异常处理,而不是为自己不成熟的代码擦屁股。