Prev: Python3Ⅲ:函数 & 模块
Next: Python3Ⅴ:更多类型
1 异常
1.1 异常(一)
你之前已经见过[ruby=exceptions]异常[/ruby]了。如果你的代码出事,例如运行不正确的代码或处理不正确的输入时,就会产生异常,程序立即停止。 下面的代码通过尝试计算7 / 0来产生一个ZeroDivisionError。
输出:
Part题: 异常是什么? A. 变量 B. 程序出错时产生的事件 C. 函数 |
1.2 异常(二)
由于不同的出错原因,会产生不同的异常。 常见的异常有: ImportError:导入失败 IndexError:访问列表时索引越界 NameError:使用了未知的变量名 SyntaxError:代码不能被正确解析 TypeError:调用函数时传递了不恰当类型的值 ValueError:调用函数时传递了恰当类型但有不恰当的值的值 Python还有一些内置异常,例如ZeroDivisionError和OSError。第三方库也常常定义自己的异常。 Part题: 下面代码会跑出什么异常?
A. ValueError B. TypeError C. ZeroDivisionError |
2 异常处理
2.1 异常处理(一)
若要处理异常,或在发生异常时执行特定代码,你可以用try/except语句。 try语句块包含着可能会抛出某种异常的代码。如果那种异常发生了,try代码块停止执行,转而执行except代码块。如果异常没有发生,那么except代码块不会运行。 举例:
结果:
上面的代码中,except语句标明了要处理的异常类型(本例中是ZeroDivisionError)。 Part题: 下面代码的输出是?
A.
B.
C.
|
2.2 异常处理(二)
一个try语句可以有几个except语句来处理不同的异常。 一个except语句也可以处理多种异常,通过将异常列表写进括号内。
结果:
Part题: 下面代码的输出是?
A.
B.
C.
|
2.3 异常处理(三)
一个不标注异常类型的except语句会处理所有异常。应该少用这种语法,因为有时这会捕获未预料到的异常并掩盖出现的错误。 举例:
输出:
异常处理在与用户输入打交道时往往会很有用。 Part题: 填空以处理所有可能的异常。
|
3 finally
3.1 finally(一)
如果要保证某些代码不管有没有异常都要运行,可以使用finally语句。finally语句置于try/except语句的最后。finally代码块会在try代码块或except代码块执行后执行。
输出:
Part题: 下面代码的输出是?
A.
B.
C.
D.
|
3.2 finally(二)
即使之前有一个未被捕获的异常发生,finally代码块也会运行。
结果
Part题: 用选项填空,组成一个完整的try/except/finally块。
|
4 抛出异常
4.1 抛出异常(一)
用raise语句抛出异常。
输出
你必须指出要抛出的异常类型。 Part题: 下面的代码会产生什么错误?
A. 没有 B. ValueError C. ZeroDivisionError D. ZeroDivisionError和ValueError |
4.2 抛出异常(二)
异常可以带着一些描述信息被抛出。例
输出
Part题: 填空,如果输入是负数,就抛出一个ValueError异常。
|
4.3 抛出异常(三)
在except块中,可以不加参数的使用raise语句来重抛出任意它捕获的异常。 举例:
结果:
Part题: 在except块之外能使用raise语句么? |
5 断言
5.1 断言(一)
[ruby=assertion]断言[/ruby]是一种合理性检查,你可以在测试完程序后启用或关闭。 先测试一个表达式,如果结果为假,就抛出异常。 断言用assert语句来执行。
结果:
程序员常在函数起始放置断言检验输入是否有效,并在调用函数后检测输出是否有效。 Part题: 下面代码输出的最大数是?
|
5.2 断言(二)
assert可以有第二个参数,当断言失败时作为实参传递给AssertionError。
输出
AssertionError与任何其他异常一样可以用try-except语句捕获,但如果不处理的话,它会中止程序执行。 Part题: 填空定义一个有一个参数的函数。断言这个参数必须是正数。
|
6 打开文件
6.1 打开文件(一)
你可以用Python读写文件内容。 文本文件是最容易操作的。但在编辑文件之前,我们必须先用open函数打开一个文件。
open函数的参数是文件的路径。如果文件在当前程序路径下,你可以只写文件名。 Part题: 哪个函数用来访问文件? |
6.2 打开文件(二)
你可以在open函数的第二个参数中指定打开文件的模式。 传入"r"代表将文件以读取方式打开。这是默认值。 传入"w"代表将文件以写入模式打开,这会覆写文件。 传入"a"代表追加模式,在文件末尾加入新内容。 模式后加"b"将文件以二进制模式打开,用来操作非文本文件(例如图像或音频文件)。 举例:
在上面的模式中用+号会赋予对文件额外的操作权限。例如,r+将文件以读写模式打开。 Part题: 用选项填空,以二进制读模式打开"test.bin"文件。
|
6.3 打开文件(三)
打开并操作文件后,你应该记得关闭它。 用文件对象的close方法这么做。
之后会讲如何读写文件内容。 Part题: 如何关闭文件对象text_file? A. text_file.close() B. close(text_file) C. close("text_file") |
7 读取文件
7.1 读取文件(一)
以读模式打开的文件的内容可以用read方法读取。
这会输出"filename.txt"文件的内容。 Part题: 重排下列代码,打开文件,读取并输出文件内容,之后关闭文件。
|
7.2 读取文件(二)
若要定量读取文件,你可以给read方法提供一个数作为参数。这会决定要读取的字节数。 你可以对同一个文件对象调用很多次read来逐字节读取文件。不加参数时,read返回所有剩余的文件内容。
传递负数参数与不传递参数一样,返回剩余的所有内容。 Part题: 如果每个字符为一字节,下面的代码每一行会输出几个字符?
|
7.3 读取文件(三)
如果所有的文件内容都读取完了,任何继续尝试从文件读取的行为会返回空字符串,因为你尝试从文件末读内容。
结果:
与不传参一样,负参数返回所有内容。 Part题: 填空打开文件,读取其内容并输出内容长度。
|
7.4 读取文件(四)
若要读取文件的每一行,可以用readlines方法返回一个列表,列表元素是文件的每一行内容。 举例:
结果:
你也可以用一个for循环迭代文件每行的内容。
结果:
在输出中,每一行又被一个空行所隔开,因为print函数在输出后又会添加一个换行。 Part题: 如果file.txt文件有7行,那么下面的表达式返回什么?
|
8 写入文件
8.1 写入文件(一)
用write方法可以将一个字符串写入文件。 例:
结果:
如果文件不存在,"w"模式会创建它。 Part题: 哪一行会将"Hello world!"写入文件? A. write(file, "Hello world!") B. file.write("Hello world!") C. write("Hello world!", file) |
8.2 写入文件(二)
当文件以写模式打开时,现有文件的内容会被删除。
输出
如你所见,文件内容被覆写了。 Part题: 如果将一个文件以读模式打开后立即关闭会怎么样? A. 文件被写入一个空行 B. 文件内容被删除 C. 无事发生 |
8.3 写入文件(三)
write方法调用成功时返回实际写入的字节数。
输出:
若要写入非字符串对象,你需要先将其转换为字符串。 Part题: 如果一次文件写入操作成功,下面哪个语句会计算为真? A. file.write(msg) == True B. file.write(msg) == msg C. file.write(msg) == len(msg) |
9 运用文件
9.1 运用文件(一)
使用文件后永远关闭文件以防止资源浪费是好习惯。一种方法是用try和finally。
这会保证即使有错误发生,文件也会被关闭。 Part题: 下面代码中会调用close()方法吗?
|
9.2 运用文件(二)
另一种方法使用with语句。这会创建一个临时变量(通常叫f),只在with语句块内能访问。
在with块执行结束后,即使出错,文件也会被自动关闭。 Part题: 填空创建一个有效的with语句块,并读取文件内容。
|
期末考试
1. 下面代码不会输出哪个数字?
A. 2 B. 3 C. 4 2. 将文件以二进制读模式打开。
3. 填空尝试打开并读取文件。若有异常产生,输出错误信息。
4. 下面代码输出的最大数是?
|