Python学习笔记(五)异常处理与文件
1.错误处理:
当我们认为某些代码可能会出错时,就可以用
try来运行这段代码,如果执行出错,则后续代码不会继续执行,而是直接跳转至错误处理代码,即
except语句块,执行完
except后,如果有
finally语句块,则执行
finally语句块,至此,执行完毕。
[code]try: print('try...') r = 10 / 0 print('result:', r) except ZeroDivisionError as e: print('except:', e) finally: print('finally...') print('END') """输出如下: try... except: division by zero finally... END"""
Python的错误其实也是class,所有的错误类型都继承自
BaseException,所以在使用
except时需要注意的是,它不但捕获该类型的错误,还把其子类也“一网打尽”。比如
[code]try: foo() except ValueError as e: print('ValueError') except UnicodeError as e: print('UnicodeError')
第二个
except永远也捕获不到
UnicodeError,因为
UnicodeError是
ValueError的子类,如果有,也被第一个
except给捕获了。
使用
try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数
main()调用
foo(),
foo()调用
bar(),结果
bar()出错了,这时,只要
main()捕获到了,就可以处理。
2.调试
i.第一种方法简单直接粗暴有效,就是用
print()把可能有问题的变量打印出来看看。
ii.断言:
assert的意思是,表达式
n != 0应该是
True,否则,根据程序运行的逻辑,后面的代码肯定会出错。如果断言失败,
assert语句本身就会抛出
AssertionError:
[code]def foo(s): n = int(s) assert n != 0, 'n is zero!' return 10 / n def main(): foo('0') """输出如下 $ python err.py Traceback (most recent call last): ... AssertionError: n is zero! """
iii.把
print()替换为
logging是第3种方式,和
assert比,
logging不会抛出错误,而且可以输出到文件:
[code]import logging logging.basicConfig(level=logging.INFO) s = '0' n = int(s) logging.info('n = %d' % n) print(10 / n) """输出如下 INFO:root:n = 0 Traceback (most recent call last): File "err.py", line 8, in <module> print(10 / n) ZeroDivisionError: division by zero """
这就是
logging的好处,它允许你指定记录信息的级别,有
debug,
info,
warning,
error等几个级别,当我们指定
level=INFO时,
logging.debug就不起作用了。同理,指定
level=WARNING后,
debug和
info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
logging的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。
iiii.第4种方式是启动Python的调试器pdb,让程序以单步方式运行,可以随时查看运行状态。
iiiii.pycharm等IDE
3.测试:单元测试与文档测试
4.IO编程:
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。
由于CPU和内存的速度远远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。举个例子来说,比如要把100M的数据写入磁盘,CPU输出100M的数据只需要0.01秒,可是磁盘要接收这100M数据可能需要10秒,怎么办呢?有两种办法:
第一种是CPU等着,也就是程序暂停执行后续代码,等100M的数据在10秒后写入磁盘,再接着往下执行,这种模式称为同步IO;
另一种方法是CPU不等待,只是告诉磁盘,“您老慢慢写,不着急,我接着干别的事去了”,于是,后续代码可以立刻接着执行,这种模式称为异步IO。
同步和异步的区别就在于是否等待IO执行的结果。
5.读写文件:
读文件:
[code]f=open('tips.txt','r') # 相对路径 print(f.read()) f.close() fs=open('D:/临时文件/test.txt','r') # 绝对路径 print(fs.read()) fs.close()
使用python内置的open()函数以读文件模式打开文件,如果文件不存在,
open()函数就会抛出一个
IOError的错误。如果文件打开成功,接下来,调用
read()方法可以一次读取文件的全部内容,Python把内容读到内存,用一个
str对象表示。最后一步是调用
close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的。
由于文件读写时都有可能产生
IOError,一旦出错,后面的
f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用
try ... finally来实现:
[code]try: f = open('/path/to/file', 'r') print(f.read()) finally: if f: f.close()
但是每次都这么写实在太繁琐,所以,Python引入了
with语句来自动帮我们调用
close()方法:
[code]with open('/path/to/file', 'r') as f: print(f.read())
调用
read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用
read(size)方法,每次最多读取size个字节的内容。另外,调用
readline()可以每次读取一行内容,调用
readlines()一次读取所有内容并按行返回
list。因此,要根据需要决定怎么调用。
如果文件很小,
read()一次性读取最方便;如果不能确定文件大小,反复调用
read(size)比较保险;如果是配置文件,调用
readlines()最方便:
[code]for line in f.readlines(): print(line.strip()) # 把末尾的'\n'删掉
以下分别是逐行读取文件内容和逐行将文件内容保存到列表:
[code]with open('tips.txt','r') as f: for line in f: print(line.rstrip()) with open('tips.txt') as f: lines = f.readlines() print(lines)
字符编码:要读取非UTF-8编码的文本文件,需要给
open()函数传入
encoding参数,遇到有些编码不规范的文件,你可能会遇到
UnicodeDecodeError,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况,
open()函数还接收一个
errors参数,表示如果遇到编码错误后如何处理。最简单的方式是直接忽略,例如,读取GBK编码的文件:
[code]f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
打开模式:
# r 以只读方式打开文件。这是默认模式。文件必须存在,不存在抛出错误
#rb 以二进制格式打开一个文件用于只读。
#r+ 打开一个文件用于读写。文件指针将会放在文件的开头。读完就追加。
#w 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
#w+ 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
#a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
#a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
注:后面有带b的方式,不需要考虑编码方式。有带+号的,则可读可写,不过它们之间还是有区别的
文件路径:有相对和绝对两种,注意采用 ' \ ' 可能会形成转义字符,建议使用' / '
写文件:
[code]f = open('tests.txt', 'w') f.write('Hello, world!') f.close()
写文件和读文件是一样的,唯一区别是调用
open()函数时,传入标识符
'w'或者
'wb'表示写文本文件或写二进制文件。以
'w'模式写入文件时,如果文件已存在,会直接覆盖(相当于删掉后新写入一个文件)。如果我们希望追加到文件末尾怎么办?可以传入
'a'以追加(append)模式写入。可以反复调用
write()来写入文件,但是务必要调用
f.close()来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用
close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用
close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用
with语句来得保险。
6.StringIO和BytesIO:
很多时候,数据读写不一定是文件,也可以在内存中读写。StringIO顾名思义就是在内存中读写str。要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:
[code]>>> from io import StringIO >>> f = StringIO() >>> f.write('hello') 5 >>> f.write(' ') 1 >>> f.write('world!') 6 >>> print(f.getvalue()) hello world!
getvalue()方法用于获得写入后的str。要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:
[code]>>> from io import StringIO >>> f = StringIO('Hello!\nHi!\nGoodbye!') >>> while True: ... s = f.readline() ... if s == '': ... break ... print(s.strip()) ... Hello! Hi! Goodbye!
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。
7.操作文件和目录
相关函数一部分放在os模块中,一部分放在os.path模块中!查看,创建,删除目录方法如下:
[code]import os import os.path print(os.path.abspath('.')) # 查看当前目录的绝对路径 print(os.path.join('D:/', 'testdir')) # 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来: os.mkdir('D:/testdir') # 然后创建一个目录 os.rmdir('D:/testdir') # 删掉一个目录 print(os.path.splitext('D:/testdir')) # 得到文件扩展名
把两个路径合成一个时,不要直接拼字符串,而要通过
os.path.join()函数,这样可以正确处理不同操作系统的路径分隔符。同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过
os.path.split()函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名。
os.path.splitext()可以直接让你得到文件扩展名,很多时候非常方便。
文件操作使用下面的函数。假定当前目录下有一个
test.txt文件:
[code]os.rename('test.txt', 'test.py') # 对文件重命名 os.remove('test.py') # 删掉文件
shutil模块提供了
copyfile()的函数,你还可以在
shutil模块中找到很多实用函数,它们可以看做是
os< 20000 /code>模块的补充。要列出当前目录下的所有目录,只需要一行代码:
[code]print([x for x in os.listdir('.') if os.path.isdir(x)])
要列出所有的
.py文件,也只需一行代码:
[code]print([x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py'])
8.序列化:主要用到pickle.dumps(),json.dumps()两种函数,详情略。
- [Python]学习笔记之文件和异常
- Python学习笔记总结(四)异常处理
- Python学习笔记整理(十七)异常处理
- 阿齐兹的Python学习笔记——文件与异常
- python学习笔记2 Python文件处理
- "Python"学习笔记----简单文件处理
- [python自学笔记]匿名函数和文件处理、异常
- Python学习笔记--异常处理
- java学习笔记7 - Spring mvc 统一异常处理和静态文件的配置
- Python中的异常处理相关语句基础学习笔记
- Python中的异常处理相关语句基础学习笔记
- python学习笔记(九)异常处理
- Python学习笔记ucas(lecture3)文件处理
- 二级python学习笔记5:程序的异常处理
- Python学习笔记 Day11 文件和异常
- 学习笔记-小甲鱼Python3学习第三十二、三十三讲:异常处理:你不可能总是对的
- Python学习笔记之错误处理(关键词:错误处理、异常机制、try、except、else、finally、raise)
- Python3.3 学习笔记5 - 异常处理
- python 学习笔记(10)重构与文件处理
- python学习(二)之文件处理与错误异常