您的位置:首页 > 编程语言 > Python开发

阿齐兹的Python学习笔记——文件与异常

2018-02-04 14:02 766 查看

文件与异常

如何从文件读取数据

Python的基本输入机制是基于行的:从文本文件中读入序数据时,一次会读一个数据行

Python的BIF
open()
就是用来与文件交互的。处理数据时,会创建一个迭代器从文件向你的代码输入一行一行的数据。Python文件输入机制的标准是“打开-处理-关闭”

the_file = open('sketch.txt')
# Do something with the data in "the_file"
the_file.close()


如果与for循环相结合,可以很容易地读取文件

实例:

>>> import os  #从标准库中导入“os”
>>> os.getcwd() #查看当前目录
'C:\\Python34'
>>> os.chdir('C:/Users/0AQZ0/Documents/exercisecode/Python/HeadFirstPython/chapter3') #切换当前工作目录
>>> os.getcwd() #确认现在在正确的目录下
'C:\\Users\\0AQZ0\\Documents\\exercisecode\\Python\\HeadFirstPython\\chapter3'
>>> data = open('sketch.txt') #打开一个文件,并赋值给名为“data”的文件对象
>>> print(data.readline(), end='') #使用readline()获取一个数据行
Man: Is this the right room for an argument?
>>> print(data.readline(), end='')
Other Man: Ive told you once.
>>> data.seek(0) #使用seek()方法返回文件初始位置。对Python文件也可以用tell()
0
>>> for each_line in data:
print(each_line, end='') #对文件数据进行迭代输出

Man: Is this the right room for an argument?
Other Man: Ive told you once.
Man: No you havent!
Other Man: Yes I have.
Man: When?
Other Man: Just now.
Man: No you didnt!
Other Man: Yes I did!
Man: You didnt!
Other Man: Im telling you, I did!
Man: You did not!
Other Man: Oh Im sorry, is this a five minute argument, or the full half hour?
Man: Ah! (taking out his wallet and paying) Just the five minutes.
Other Man: Just the five minutes. Thank you.
Other Man: Anyway, I did.
Man: You most certainly did not!
Other Man: Now lets get one thing quite clear: I most definitely told you!
Man: Oh no you didnt!
Other Man: Oh yes I did!
Man: Oh no you didnt!
Other Man: Oh yes I did!
Man: Oh look, this isnt an argument!
(pause)
Other Man: Yes it is!
Man: No it isnt!
(pause)
Man: Its just contradiction!
Other Man: No it isnt!
Man: It IS!
Other Man: It is NOT!
Man: You just contradicted me!
Other Man: No I didnt!
Man: You DID!
Other Man: No no no!
Man: You did just then!
Other Man: Nonsense!
Man: (exasperated) Oh, this is futile!!
(pause)
Other Man: No it isnt!
Man: Yes it is! #注:由于格式问题,省去很多处的单引号
>>> data.close() #处理完文件后要将它关闭


用split()进一步查看数据

split()
方法可以将一个字符串分开,返回一个字符串列表,并赋值给一个目标标识符列表,这称为多重赋值(multiple assignment)

示例:

(role, line_spoken) = each_line.split(':')


这会把
:
前面的字符串赋值给目标标识符列表
role
,后面的字符串赋值给目标标识符列表
line_spoken


存在的问题1:

ValueError: too many values to unpack (expected 2)

出现的原因:

一行数据中有多个冒号,split()无法正常工作

解决方法:

>>> help(each_line.split)
Help on built-in function split:

split(...) method of builtins.str instance
S.split(sep=None, maxsplit=-1) -> list of strings

Return a list of the words in S, using sep as the
delimiter string.  If maxsplit is given, at most maxsplit
splits are done. If sep is not specified or is None, any
whitespace string is a separator and empty strings are
removed from the result.


split()的可选参数maxsplit可以控制将数据分解为多少个部分,默认地数据会尽可能的分解。将这个参数设置为1,则只会分解为两个部分

import os
os.getcwd()
os.chdir('C:/Users/0AQZ0/Documents/exercisecode/Python/HeadFirstPython/chapter3')
os.getcwd()
data = open('sketch.txt')
for each_line in data:
(role, line_spoken) = each_line.split(':', 1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')


IDLE提供了Help->Python Docs菜单选项,可以利用这个菜单搜索整个Python文档,也可以在Shell中使用help() BIF

存在的问题2:

ValueError: need more than 1 value to unpack

出现的原因:

有些数据行不包含冒号,由于缺少冒号,split()无法完成它的工作

解决方法1:

增加必要的逻辑来确保是否可以在数据行上调用split()

缺点:需要更多的代码,增加复杂性,而且可能会出现没考虑到的错误

解决方法2:

先尝试运行代码,然后处理可能的错误

优点:减少了代码的复杂性

利用find()增加额外逻辑

find()
BIF:可以尝试找出一个字符串中的子串,如果无法找到,find()会返回值-1

如果find()可以找到子串,这个方法会返回子串在原字符串中的索引位置

示例:

>>> each_line = "I tell you, there's no such thing as a flying circus."
>>> each_line.find(':')
-1
>>&g
4000
t; each_line = "I tell you: there's no such thing as a flying circus."
>>> each_line.find(':')
10


我的代码:

import os
os.getcwd()
os.chdir('C:/Users/0AQZ0/Documents/exercisecode/Python/HeadFirstPython/chapter3')
os.getcwd()
data = open('sketch.txt')
for each_line in data:
if each_line.find(':')!=-1:
(role, line_spoken) = each_line.split(':', 1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')
else:
print(each_line, end='')

data.close()


条件可改成
if not each_line.find(':') == -1:
,使用not关键字将条件的值取反

先尝试,然后恢复

异常(exception):Python通过traceback来告诉你运行时发生了某种意外情况

Python允许你在异常发生时捕获异常,为你提供了一个机会,可以从这个错误中恢复,同时避免程序崩溃。所以,可以先尝试运行代码,然后处理可能发生的错误

Python的异常处理机制:这个机制允许错误的出现,但监视它的发生,然后给你一个机会来恢复。在异常控制流期间,Python先尝试运行你的代码,如果发现有问题,就会执行恢复代码,然后继续正常执行你的代码

try/except机制

Python有一个try语句,这个语句允许你在运行时系统地处理异常和错误

try语句的一般形式:

try:
#你的代码(可能导致一个运行时的错误)
except:
#错误恢复代码


为什么允许错误的发生?

因为如果针对每个可能的错误编写代码,思考额外的逻辑需要花很多时间

值得注意的问题

列表的分类:

Python中实际上有两种列表:一种是可以改变的列表(用中括号包围),另一种是创建后不能改变的(用小括号包围),又称为“元组”(tuple)。元组中的数据在任何情况下都不能改变。split()传回一个列表,目标标识符包围在小括号中,而不是中括号,说明它是一个tuple。

放过错误

对于一些数据,最好能忽略不符合期望格式的数据行。如果某个方法调用导致一个异常,可以报告这是一个错误,并使用pass继续执行代码。

pass语句的适应情景:你需要提供一些代码,但是并不需要具体做什么(可以把它认为是空语句或null语句)

我的代码:

import os
os.getcwd()
os.chdir('C:/Users/0AQZ0/Documents/exercisecode/Python/HeadFirstPython/chapter3')
os.getcwd()
data = open('sketch.txt')
for each_line in data:
try: #try后面的代码得到保护,可以避免运行时的错误
(role, line_spoken) = each_line.split(':', 1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')
except: #如果出现一个运行时错误,会执行这个代码
pass

data.close()


其他错误

IOError:由于缺少数据文件,程序出现崩溃

>>>
Traceback (most recent call last):
File "C:/Users/0AQZ0/Documents/exercisecode/Python/sketch2.py", line 5, in <module>
data = open('sketch2.txt')
FileNotFoundError: [Errno 2] No such file or directory: 'sketch2.txt'


解决方法1:

增加更多的错误检查代码

os模块中有一个工具可以帮助确定一个数据文件是否存在

import os

if os.path.exists('sketch.txt'): #检查文件是否存在
data = open('sketch.txt')
for each_line in data:
if each_line.find(':')!=-1:
(role, line_spoken) = each_line.split(':', 1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')
else:
print(each_line, end='')
data.close()
else:
print('The data file is missing')


解决方法2:

再增加一层异常处理

import os
try:
data = open('sketch2.txt')
for each_line in data:
try:
(role, line_spoken) = each_line.split(':', 1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')
except:
pass
data.close()
except:
print('The data file is missing')


通过使用Python的异常处理机制,你可以关注代码真正需要做什么,而不必操心哪里可能出问题,增加代码的复杂性以至于掩盖程序本来的作用

要重点关注你的代码需要做什么

特定指定异常

以一种不那么一般化的方式使用except,避免代码悄无声息地忽略运行时的错误

在except代码行上指定错误类型,就可以把一般化的异常处理代码转变为具有特定性

try:
data = open('sketch.txt')
for each_line in data:
try:
(role, line_spoken) = each_line.split(':', 1)
print(role, end='')
print(' said: ', end='')
print(line_spoken, end='')
except ValueError: #指定要处理的运行时的错误
pass
data.close()
except IOError: #指定要处理的运行时的错误
print('The data file is missing')


如果出现一个不同类型的运行时错误,你将对这个异常有所认识

小结

什么是异常

处理异常时的两种方法

try/except异常处理机制、pass语句

BIF: help()、open()、readline()、seek()、close()、split()、find()

列表的分类

如何在IDLE中获得帮助
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python