从零开始学Python(七):文件存储I/O流和异常捕捉
这两天在搞小程序开发,耽搁了一下更新的进度,今天补上.一个完整的前端程序肯定离不开数据存储和网络两个模块,今天我们就先来讲讲python中的一种常见数据存储:文件存储!~!
文件存储(I/O操作)
何为I/O?
I/O分别对应着英文input和output的缩写,代表着输入和输出.分别对应着我们文件的读和写的过程,
当我们对一个文件进行读取的操作的时候,程序会以我们要读取的文件为目标,通过输入流操作,将文字读取到缓存区,以便以后调用.
当我们对一个文件进行写的操作的时候,程序会将我们存在缓冲区中的数据通过输出流写到我们的目标文件里.
Python的键盘输入
python中等待键盘的函数有两个,raw_input和input,两者作用效果相同,记录键盘的输入并返回结果.
s=raw_input('请输入任意内容:\n')
print '输出:'+s
>>>请输入任意内容:
hello
输出:hello
raw_input函数返回的是一个字符串对象,我们可以直接打印出输入结果.
s=input('请输入任意内容:\n')
print '输出:',s
>>>请输入任意内容:
5*6
输出: 30
input函数返回的是一个对象,他和raw_input的根本区别是可以输入表达式,并且返回表达式的结果.
Python文件操作
Python的文件操作都是由file对象处理.
open函数
file object = open(file_name [, access_mode][, buffering])
Python提供了内置函数open来获取file对象,这里我们仔细的讲解一下相关此参数的作用.
- file_name 文件路径.代表着我们要写入的文件名或者我们要读取的文件,注意:这里的路径是相对路径,相对于我们程序所在目录的路径
- access_mode 打开文件的模式.可不填,默认为只读.也可根据需求改变,以下是全部的模式.
模式 | 说明 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
- buffering 用于设置缓存策略
在二进制模式下,使用0来切换缓冲;在文本模式下,通过1表示行缓冲(固定大小的缓冲区)。
在不给参数的时候,二进制文件的缓冲区大小由底层设备决定,可以通过io.DEFAULT_BUFFER_SIZE获取,通常为4096或8192字节
我们简单的举个例子:(test.py文件代码)
test.py文件代码,f/b
f=open('f/b.txt') #我们读取本模块目录下的f文件夹中的b.txt文件,其他两个参数默认
print f
prin io.DEFAULT_BUFFER_SIZE
>>> <open file 'f/b.txt', mode 'r' at 0x1028581e0> #可以发现文件对象默认模式是r
8192 #设备默认缓冲区为8192字节(注意,这里需要导入io模块才可使用io函数)
File对象相关函数
通过Python的open函数我们可以得到File对象,而文件存储的操作就是针对file对象来进行的.
file对象有几个常用的函数,下面我们来一一讲解:
close函数
close函数的作用是刷新缓冲区.并关闭file对象的操作流,此后便不能再进行读写操作了.当这个file对象再指定到新的文件对象时,file对象会先关闭以前的文件对象.所以,当我们对一个文件操作完毕之后,应当养成良好的关闭习惯,也就是调用close函数
f=open('f/b.txt')
f.close()
write函数
write函数是file对象的数据写入函数,通过该函数可以将我们的字符串数据或者二进制数据写入到文件夹中.需要注意的是,如果我们需要数据换行,要另外写入换行符.
该函数需要有文件的写权限
f=open('f/b.txt','a+') #这里我们制定了文件模式是读写模式(具体可参考上面的表),并且指针放在末尾
f.write('我是一个小小的python爱好者,我在学习python')
f.write('虽然学习之路艰辛\n但我不放弃') #注意这里我们中间加了一个换行符
f.close() #操作完毕关闭对象
执行以上代码之后,你可以去相关目录打开b.txt文件查看内容:(但我不放弃这句因为换行单独成一行了)
我是一个小小的python爱好者,我在学习python虽然学习之路艰辛
但我不放弃
read函数
f.read(n) #参数n表示读取的文件长度,这里的长度是字节长度,参数不填的时候默认为默认缓冲区大小,上面我们打印过,是8192个字节长度
Tips:一个gbk编码的汉字占二个字节,一个utf-8编码的汉字占三个字节.(所以要想输出一个完整的utf-8的字符,最少长度要为3)
read是从一个打开的文件对象中读取数据.
f=open('f/b.txt','a+')
f.seek(0) #seek是定位函数,由于我们使用了a+文件模式,导致文件操作指针永远在最后面,而最后面是没有数据的,所以我们将光标恢复到开头,这样我们就可能读取到数据了.
str=f.read() #
f.close()
print str
>>> 我是一个小小的python爱好者,我在学习python虽然学习之路艰辛
但我不放弃
其实read函数还有几个衍生的方法,比如readline,读取一行,大家可以自己试试.
seek和tell函数
seek()和tell()是两个文件定位函数,一个是设置文件的操作位置,一个是获取文件的操作位置(注意:我们平常的文件读写操作都是会改变文件的操作位置的),有时候我们可能需要在某一段字符串的中间插入一端字符串,这时我们就可以利用定位函数来达到我们的需求.
f=open('f/b.txt','r+')
f.seek(0) #设置光标从0开始读
str=f.read(27)
print str
f.seek(27) #设置从位置27字节开始写
f.write('哈哈哈')
f.close()
>>> 我是一个小小的python哈哈哈,我在学习python虽然学习之路艰辛
但我不放弃
上面的例子中,我们直接在中间插入了'哈哈哈'字符
文件删除
文件删除我们需要用到python的os模块,使用时需要导入该模块.
使用os模块的remove方法开始删除
os.remove(filepath) #参数传我们需要删除的文件路径
以上就是我们文件操作,从创建,读写,到删除的整个过程,当然我们因为是入门篇,只是介绍了最基本的用法,不过万事不变其宗,基础牢固了,我们才能更好的向外拓展!学习之路慢慢其修远兮!
Python异常
什么是异常
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
当我们的程序出现错误的时候,编译器都会告诉我们错误的地方,可是当我们程序上线之后,一旦遇到错误,程序便会宕机,这是我们不能容忍的,这时候就需要用到异常处理了.
python标准异常
首先我们来看个表,里面基本罗列了python中我们所有会遇到的异常(不用一一记住,脑袋过一遍就可以了):
异常名称 | 异常描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
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 | 用户代码生成的警告 |
异常的捕捉和处理
python中的异常捕捉处理和java或者oc差不多.都是一个代码块:
try:
#可能会出现异常的代码
except Exception as e:
#出现异常的信息,这里我们可以将错误信息上传
else:
#如果没有异常发生
finally:
#这里的代码不管出不出现异常都会调用,可以用来做一些文件关闭,索引关闭的操作
我们来做个简单的异常捕捉的例子:
f=None
try:
f = open('f/b.txt', 'r+') #这里我们打开一个f目录下的b.txt文件,其实这个文件是不存在的,应该会发生异常
except Exception as e: #这里我们使用的是异常的基类,可以先删除所有异常,毕竟有时候我们也不知道到底发生的异常是属于哪个类(当然,精确点总是更好的)
print e #我们将异常打印出来
finally:
if f:
f.close() #不管发没发生异常,我们都希望f对象存在的时候要关闭操作
>>> [Errno 2] No such file or directory: 'f/b.txt' #确实发生了文件或者目录找不到的异常
以上就是异常的的常用用法,是不是很简单,日常开发中,我们可能会遇到很多异常处理,我们需要根据自己的需求对代码块进行更改,以便以我们的代码可以抗拒任何恶劣的环境.
Q&A
到这里,我们这一章就讲完了.到了这里,我们已经算是入门了,基本的python语法,对象,函数,写法,我们都已经学会了,下一章开始,我们学习一点更加深一点的东西,多线程