异常和文件
异常
程序在运行过程当中的错误,比如没有赋值过的变量,数组下标越界等.异常会导致程序终止
语法:
try:
代码块1(可能出错的语句)
except:
代码块2(出错时语句)
else:
代码块3(没出错时要执行的语句)
没有出错的时候执行代码块13(else也可以不写)
出错了就执行代码块2
try:
10/0
except Exception as e:
print(e,type(e))
else:
print('1')
finally:
print('2')
#(ZeroDivisionError('integer division or modulo by zero',), <type 'exceptions.ZeroDivisionError'>)
#2
异常的传播:
当函数没有对异常进行处理会将异常像外层传播,这就是所谓的抛异常
当程序运行过程中出现异常时,所有的异常信息都会保存到专门的异常对象中,抛异常抛的就是异常对象eg:NameError
在Python为我们提供了多个异常对象,在Python文档中eg:IndexError/keyError …
如果except后面不更任何内容(或者更的是所有异常的父类Exception),则此时将会捕获所有异常,如果在except后直接更异常类型则只会捕捉该类型的异常
try:
print(a)
print(10/0)
except NameError:
print('NameError')
except ZeroDivisionError:
print('ZeroDivisionError')
else:
print('1')
finally:
print('2')
#NameError
#2
异常的抛出
这里指的是主动抛出异常
语法:raise Exception(‘message’) 用于向外部抛出异常,后边可以更一个异常类,或者异常类的实例
def add(a,b):
if(a<0 or b<0):
raise Exception('can not < 0')
# 这里可以return None也可以 但是如果这个问题强制要处理最好还是抛异常
r=a+b
return r
print(add(1,-2))
这里的应用场景举例:比如这个是一个结账的函数,你传入的参数不符合要么库存不够,要么金额小于0这种异常,不应该在结账函数的内部进行处理,因为这是一个结账函数只负责结账.
自定义异常
创建类继承exception就行
class MyError(Exception):
pass
def add(a,b):
if(a<0 or b<0):
raise MyError('can not < 0')
r=a+b
return r
print(add(1,-2))
# __main__.MyError: can not < 0
文件(file)
-
通过Python程序对计算机中的各种文件进行增删改查操作
-
I/O(input/output)
操作文件步骤
- 打开文件
- 读写,保存
- 关闭文件
打开文件
使用open()函数来打开文件
参数:
file:要打开文件的名字
file_name='demo.txt'
# 如果要打开的文件和当前文件在同一目录下,直接写文件名就可以,否则直接写绝对路径 windows中可以使用/代替\ 或者使用\\
# file_name='hello/demo2.txt'
file_obj=open(file_name)# 打开文件
读取文件
file_name='hello/demo2.txt'
file_obj=open(file_name)
content=file_obj.read()
print(content)
# i love you more than i can say
关闭文件
file_name='hello/demo2.txt'
file_obj=open(file_name)
content=file_obj.read()
print(content)
file_obj.close()# 不常用 很可能被忽略 关了后不能在操作了
with … as 语句
file_name='hello/demo2.txt'
with open(file_name) as file_obj:#此时这个文件只能在with中使用一旦with结束文件会自动close()
content=file_obj.read()
print(content)
合体版
file_name='hello/demo2.txt'
try:
with open(file_name) as file_obj:
content=file_obj.read()
print(content)
except FileNotFoundError:
print(file_name+'no exist')
调用open()来打开一个文件,可以将文件分成俩种类型
一种是纯文本文件(使用utf-8编码编写的文本文件)
一种是二进制文件(图片/MP3/ppt等这些文件)
open()打开文件时默认是用文本文件打开的,处理文本文件时,指定文件编码为utf-8 (Python2中不要指定会报错)
file_name='demo.txt'
try:
with open(file_name) as file_obj:
# 如果调用read()它会将所有的文本都读取出来,很容易内存溢出
#read()可以接收一个size作为参数,该参数可以指定要读取的字符的数量
#可以为size指定一个值负数表示它会读取剩下所有的字符,size的值就是read读取的指定数量
#每次读取都是从上次读取到的位置开始读取的,如果已经读取完了返回空串''
content=file_obj.read(6)
content1=file_obj.read(6)
print(content)
print(content1)
except :
print(file_name+'no exsit')
# 红豆生南国,
# 当春乃发生.
file_name='demo.txt'
try:
with open(file_name) as file_obj:
file_content=''
chunk=100
#这种方式可以避免一次读取的过多导致内存溢出 适合读取较大的文件
while True:
content=file_obj.read(chunk)
if not content:
break
file_content+=content
print(file_content,end='')
except :
print(file_name+'no exsit')
import pprint
file_name='demo.txt'
try:
with open(file_name) as file_obj:
content=file_obj.readline()
print(content)
# 返回的是所有的内容封装到一个列表中
content1=file_obj.readlines()
pprint.pprint(content1)
except :
print(file_name+'no exsit')
# 红豆生南国,
# ['当春乃发生.']
import pprint
file_name='demo.txt'
try:
with open(file_name) as file_obj:
#利用for循环读取文件
for t in file_obj:
print(t)
except :
print(file_name+'no exsit')
#红豆生南国,
#当春乃发生.
写入文件
使用open()打开文件时必须要指定打开文件所要做的操作(读/写/追加)
不指定默认是读,读的时候不能向文件中写入的,r表示可读,w(覆盖)表示只是可写的write可以分多次向文件中写入内容,只能是字符串,并且不会自动换行,写入完成之后,该方法会返回写入字符的字数,a()表示追加.
r+,w+,**a+**表示即可读又可写,文件不存在会报错
x是穿件新的文件,有的化报错
import pprint
file_name='demo.txt'
try:
with open(file_name,'a+') as file_obj:
file_obj.write(str(123456)+'\t')
except :
print(file_name+'no exsit')
读取二进制文件
读取模式
t 读取文本文件(默认值)
b 读取二进制文件
file_name='/home/zax/Videos/dde-introduction.mp4'
try:
with open(file_name,'rb') as file_obj:
new_file_name='/home/zax/Videos/aa.mp4'
with open(new_file_name,'wb') as new_file_obj:
chunk=1024
while True:
content=file_obj.read(chunk)
if not content:
break
new_file_obj.write(content)
except :
print(file_name+'no exsit')
#该功能复制了一个MP4文件
seek()和tell()
tell()就是获取当前读取的位置
seek()修改当前读取位置
注意这种方法适用与二级制文件,同样适用于文本文件,但是文本文件不好控制位置因为有的汉字是3个位,有的字母是一个位置
seek()俩个参数:
1. 是要切换的位置
2. 计算位置的方式
- 0 从头计算,(默认值)
- 1 从当前位置计算
- 从最后位置开始计算
file_name='/home/zax/Videos/dde-introduction.mp4'
try:
with open(file_name,'rb') as file_obj:
file_obj.seek(55) # seek()可以修改当前读取的位置
print(file_obj.tell())
file_obj.seek(80,0)
print(file_obj.tell())
file_obj.seek(70,1)
print(file_obj.tell())
file_obj.seek(-1,2)
print(file_obj.tell())
except :
print(file_name+'no exsit')
# 55
# 80
# 150
# 7419123
os操作文件
import os
#获取指定目录 需要一个路径作为参数 默认为. 会返回一个列表
r=os.listdir('.')
print(r)
# 获取当前目录
r=os.getcwd()
# cd
os.chdir('/home/zax')
r=os.getcwd()
#创建目录
os.mkdir('mkdirtest')
#创建文件
open('a.txt','w')
os.chdir('../')
#删除目录 只能删除空目录
os.rmdir('mkdirtest')
#删除文件不需要为空
os.remove('a.txt')
#mv
os.rename('旧名字','新名字')
print(r)