捕获异常
试图读写问件事,很多地方可能会发生错误。如果你试图打开一个不存在的恩建A级,会得到一个输入输出错误(IOError)
fin = open('bad_file')
如果没有权限访问一个文件
会得到PmissionError
fout = open('/etc/passwd','w')
如果你试图打开一个目录来读取,会得到
会得到IsADirectoryError
fin = open('/home')
为了避免这些错误,你可以使用类似os.path.exists和os.path.isfile的函数来检查,但这将会耗费大量的时间和代码去检查所有的可能性。
更好的方法是在问题出现的时候才去处理,而这正式try语句做的事情。它的语法类似if else语句
try:
fin = open('bad_file')
except:
print('smething wrong')
python从try子句开始执行。如果一切正常,那么except子句将被跳过。如果发生异常,则跳出try子句,执行except子句。
使用try语句处理异常被称为是捕获异常。
数据库
数据库是一个用来存储数据的文件。大多数的数据库采用类似字典的形式,即将键映射到值。
数据库和字典的最大区别是,数据库是存储在硬盘上,所以即使程序结束,它们依然存在。
dbm模块提供了一个创建和更新数据库文件的接口。
下例,创建一个包含图片文件标题的数据库
打开数据库和打开其它文件的方法类似
import dbm
db = dbm.open('captions','c')
模式‘c’代表如果数据库不存在则创建该数据库,这个操作返回的是一个数据库对象,可以像字典一样使用它。
当创建一个新项时,dbm将更新数据库文件
db['cleese.png'] = 'Photo'
当访问某个项时,dbm将更新数据库文件
db['cleese.png']
返回的结果是一个字节对象,这就是为什么结果以b开头。一个字节对象在很多方面和一个字符串很像。
如果你对已有的键再次进行赋值,dbm将就的值替换掉:
db['cleese.png'] = 'photo'
一些字典方法,例如keys和items,不适用于数据库对象,但是for循环依然适用:
for key in db:
print(key,db[key])
与其他文件一样,完成操作后需要关闭文件
db.close()
序列化
dbm的一个限制在于键和值必须是字符串或者字节。如果你尝试去用其它数据类型,你会得到一个错误。
pickle模块可以解决这个问题。它能将几乎所有类型的对象转化为适合在数据库中存储的字符串,以及将那些字符串还原为原来的对象。
pickle.dumps读取一个对象作为参数,并返回一个字符串表示(dumps是dump string 的缩写)
import pickle
t = [1,2,3]
pickle.dumps(t)
这个格式对人类来说不是很直观,但是对pickle来说很容易去解释。pickle.loads可以重建对象
t1 = [1,2,3]
s = pickle.dumps(t1)
t2 = pickle.loads(s)
尽管新对象和旧对象有相同的值,但他们不是同一个对象
t1 == t2
>True
t1 is t2
>Flase
换言之,序列化然后反序列化等效于复制一个对象
可以使用pickle将非字符串对象存储在数据库中。这个组合已经被封装进了模块shelve。
管道
大多数操作系统提供了一个命令行的接口,也被称为shell。shell通常提供浏览文件系统和启动程序命令。例如,在unix系统中可以使用cd改变目录,使用ls显示一个目录的内容,通过输入firefox来启动一个网页浏览器
任何可以在shell中启动的程序,也可以在python中通过使用管道对象来启动。一个管道代表一个正在运行的程序。
例如,unix命令ls-l将以详细格式显示当前目录下的内容,可以使用os.popen来启动ls
cmd = 'ls-l'
fp = os.open(cmd)
实参是一个包含shell命令的字符串。返回值是一个行为类似已打开文件的对象。可以使用readline来每次从ls进程的输出中读取一行,或者使用read来一次读取所有内容
res = fp.read()
完成操作后,像关闭一个文件一样关闭管道
stat = fp.close()
print(stat)
>None
返回值是ls进程的最终形态。None表示正常结束。