Python之错误异常和文件处理

2018-05-23  本文已影响22人  TitanCoder

错误和异常

Python 中(至少)有两种错误:语法错误和异常(syntax errorsexceptions

语法错误

语法错误,也被称作解析错误, 使我们在学习Python过程中最常遇到的错误, 来看看下面两个错误示例:

if True
    print('titan')

# 错误信息:
File "../5-读文件.py", line 19
    if True
          ^
SyntaxError: invalid syntax

异常

print(1 / 0)
# 错误信息:
File "../5-读文件.py", line 22, in <module>
    print(1 / 0)
ZeroDivisionError: division by zero


print(1 + "12")
# 错误信息:
File "../5-读文件.py", line 22, in <module>
    print(1 + "12")
TypeError: unsupported operand type(s) for +: 'int' and 'str'


print(1 + ad * 2)
# 错误信息:
File "../5-读文件.py", line 22, in <module>
    print(1 + ad * 2)
NameError: name 'ad' is not defined

异常处理

注意: 还有一些错误是无法跳过的, 比如内存错误

<div class='note info'><p>错误处理的语句 </p></div>

第一种格式

# 格式:

try:
    语句t
except 错误码 as e:
    语句1
except 错误码 as e:
    语句2
except 错误码 as e:
    语句3
    ...
except 错误码 as e:
    语句n
else:
    语句e

<div class='note warning'><p>需要注意的是: </p></div>

# 错误处理的语句(else可有可无)
try.......except....else

# 格式:
try:
    语句t
except 错误码1:
    语句1
except 错误码2:
    语句2
else:
    语句3

第二种格式

一个 except 子句可以在括号中列出多个异常的名字, 对于指定的一些异常做统一处理

try:
    print(7 / 0)
except (ZeroDivisionError, NameError):
    print('程序异常')

第三种格式

无论遇到的是哪一种异常, 均做统一处理

try:
    print(7 / 0)
except :
    print('程序异常')

try 语句工作方式

使用示例:

一个 try 语句可能包含多个 except 子句,分别指定处理不同的异常。至多只会有一个分支被执行。异常处理程序只会处理对应的 try 子句中发生的异常,在同一个 try 语句中,其他子句中发生的异常则不作处理

try:
    print(7 / 0)
except ZeroDivisionError:
    print('除数为0')
except NameError:
    print('没有改变量')
except SyntaxError:
    print('不知道')

一个 except 子句可以在括号中列出多个异常的名字

try:
    print(7 / 0)
except (ZeroDivisionError, NameError):
    print('程序异常')

最后一个 except 子句可以省略异常名称,以作为通配符使用。你需要慎用此法,因为它会轻易隐藏一个实际的程序错误!可以使用这种方法打印一条错误信息,然后重新抛出异常(允许调用者处理这个异常):

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

try … except 语句可以带有一个 else子句,该子句只能出现在所有 except 子句之后。当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。例如:

try:
    print(7 / 0)
except ZeroDivisionError:
    print('除数为0')
except NameError:
    print('没有改变量')
else:
    print('代码OK')

抛出异常

raise语句允许程序员强制抛出一个指定的异常

raise NameError('TitanJun')

# 异常信息:
Traceback (most recent call last):
  File "../1-异常处理.py", line 95, in <module>
    raise NameError('TitanJun')
NameError: TitanJun

如果你需要明确一个异常是否抛出,但不想处理它,raise 语句可以让你很简单的重新抛出该异常:

try:
    raise NameError('TitanJun')
except NameError:
    print('NameError错误')
    raise

# 错误信息:
NameError错误
Traceback (most recent call last):
  File "../1-异常处理.py", line 97, in <module>
    raise NameError('TitanJun')
NameError: TitanJun

定义清理行为

try:
    print(7 / 0)
except ZeroDivisionError:
    print('除数为0')
except NameError:
    print('没有改变量')
finally:
    print('我一定要执行')
    
# 输出:
除数为0
我一定要执行

预定义清理行为

有些对象定义了标准的清理行为,无论对象操作是否成功,不再需要该对象的时候就会起作用。以下示例尝试打开文件并把内容打印到屏幕上

for line in open("myfile.txt"):
    print(line)

这段代码的问题在于在代码执行完后没有立即关闭打开的文件。这在简单的脚本里没什么,但是大型应用程序就会出问题。with 语句使得文件之类的对象可以 确保总能及时准确地进行清理

with open("myfile.txt") as f:
    for line in f:
        print(line)

语句执行后,文件 f 总会被关闭,即使是在处理文件中的数据时出错也一样。其它对象是否提供了预定义的清理行为要查看它们的文档

文件读写

读取文件

函数 open() 返回文件对象,通常的用法需要两个参数

def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)

# 使用
path = r'/Users/xxx/text.txt'
file = open(path, 'r')

文件对象方法

read()

# 读取文件
str = file.read()
print(str)

readline()

file.readline()

遍历文件对象

可以循环遍历文件对象来读取文件中的每一行。这是一种内存高效、快速,并且代码简介的方式

for line in file:
    print(line)

<div class='note primary'><p>如果你想把文件中的所有行读到一个列表中,你也可以使用 list(file) 或者 file.readlines()</p></div>

# 把文件读到列表中
print(list(file))
print(file.readlines())

写入文件

# 写入文件
leng = file.write('我是一只小鸭子')
print(leng)
# 输出: 7


# 写入一个序列
file.writelines(['hello', 'Python'])

<div class='note warning'><p>想要写入其他非字符串内容,首先要将它转换为字符串</p></div>

tell/seek

l = file.readline()
print(l)

pos = file.tell()
print(pos)

# 输出:
b'https://www.titanjun.top/\n'
26

重新设置文件读取指针到开头

file.seek(5, 0)
print(file.readline())

# 输出:
b'https://www.titanjun.top/\n'
b'://www.titanjun.top/\n'

close

file.close()

file.read()

File "../5-读文件.py", line 64, in <module>
    file.read()
ValueError: read of closed file

关键字with

with open(path, 'rb+') as file:
    str = file.read()
    print(str)
file.close()
上一篇 下一篇

猜你喜欢

热点阅读