python学习之【异常和文件】

python学习之【异常和文件】

  • 第七章 异常和文件
    • 异常
    • 处理异常
    • 异常的传播(抛出异常)
    • 抛出异常
    • 文件(File)
      • 打开文件
      • 关闭文件
      • 文件读取
      • 文件的写入
      • 文件
      • 读取文件位置
      • 文件的其他操作

第七章 异常和文件

异常

程序在运行过程中,不可避免的出现一些错误,比如:
    使用了没有赋值过的变量
    使用了不存在的索引
    除以0
    ...
这些错误在程序中,我们称其为异常
程序运行过程中,一旦出现异常将会导致程序立即终止,异常以后的代码全部都不会执行
# print('hello')
# try:
#     # 可能出错的代码
#     # try中放置的是有可能出现的错误代码
#     print(10/0)
# except:
#     # 出错后执行的提示代码
#     # except中放置的是出错以后的处理方法
#     print('hhh,出错了')
# else:
#     print('程序正常执行')
# print('nihao')

def fn():
    print('hello fn')
    print(10/0)

def fn2():
    print('hello fn2')
    fn()

def fn3():
    print('hello fn3')
    fn2()

fn3()

处理异常

程序运行时出现异常,目的并不是让我们的程序直接终止!
Python是希望在出现异常时,我们可以编写代码来对异常进行处理

try:
    代码块(可能出现错误的语句)
except 异常类型 as 异常名:
    代码块(出现错误以后的处理方式)
except 异常类型 as 异常名:
    代码块(出现错误以后的处理方式)
except 异常类型 as 异常名:
    代码块(出现错误以后的处理方式)
...
else:
    代码块(没有错误时要执行的语句)
finally:
    代码块(该代码总会执行)
    
注意:try是必须的,else语句没有也可以
    except和finally 至少有一个   
    
可以将可能出错的代码放入到try语句中,这样如果代码没有错误,则会正常执行。
    如果出现错误,则会执行except子句中的代码,这样我们就可以通过代码来处理异常
    避免因为一个异常导致整个程序终止
print('异常出现前:')

try:
    # print(c)
    # print(10/0)
    1[0]
    1 + 'hello'
except NameError:
    # 如果except后边不跟任何的内容,此时他会铺获到所有的异常
    # 如果在except后跟着一个异常的类型,那么此时他只会铺获该类型的异常
    # print('处理异常代码')
    print('出现nameerror异常')
except ZeroDivisionError:
    print('ZeroDivisionError异常')
except IndexError:
    print('出现IndexError异常')
except Exception as e:
    # Exception是所有异常的父类,所以如果except后跟的是Exception,他也会铺获到所有的异常
    # 可以在异常类后边跟一个as xxx 此时xxx就是异常的对象
    print('未知异常',e,type(e)) # 未知异常 'int' object is not subscriptable 
finally:
    print('无论是否出现异常,该子句都会执行')
print('异常出现后')

异常的传播(抛出异常)

当在函数中出现异常时,如果在函数中对异常进行了处理,则异常不会再继续传播,
    如果函数中没有对异常进行处理,则异常会继续向函数调用处传播
    如果函数调用处处理了异常,则不再传播,如果没有处理则继续向掉员工处传播
    直到传递到全局作用域(主模块)如果依然没有处理,则程序终止,并且显示异常信息
    
当程序运行过程中出现异常以后,所有的异常信息会被保存一个专门的异常对象中
    而异常传播时,实际上就是异常对象抛给了调用处
    比如:ZeroDivisionError类的对象专门用来表示除0的异常
        NameError类的对象专门用来处理变量错误的异常
        ...
在Python为我们提供了多个异常对象
# 我们也可以自定义异常类,只需要创建一个类继承Exception即可
class MyError(Exception):
    pass
def add(a,b):
    # 如果a和b中有负数,就向调用处抛出异常
    if a < 0 or b < 0:
        # raise 用于向外部抛出异常,后边可以跟一个异常类,或异常的实例
        # raise Exception
        # 抛出异常的目的,告诉调用者,这里调用时出现问题,希望你自己处理下
        # raise Exception('两个参数中不能有负数')
        raise MyError('自定义的异常')
        # 我们也可以使用if else语句来代替异常的处理,但是不够灵活
        # return None
    r = a + b
    return r

print(add(-12,23))
# Traceback (most recent call last):
#   File "D:/python-workspace/python-base/huan/lesson_07/code/three抛出异常.py", line 10, in 
#     print(add(-12,23))
#   File "D:/python-workspace/python-base/huan/lesson_07/code/three抛出异常.py", line 5, in add
#     raise Exception('两个参数中不能有负数')
# Exception: 两个参数中不能有负数

抛出异常

- 可以使用raise语句来抛出异常,
    raise语句后需要跟一个异常类或者异常的实例

文件(File)

- 通过Python程序来对计算机中各种文件进行增删改查操作
- I/O(Input/Output)
- 操作文件的步骤:
    ① 打开文件
    ② 对文件进行个各种操作(读、写),然后保存
    ③ 关闭文件

打开文件

# open(file, mode='r', buffering=-1, encoding_=None, errors=None, newline=None, closefd=True, opener=None)
# 使用open()函数来打开一个文件
# 参数:
#     file :要打开的文件名字(路径)

# 创建一个变量,来保存文件的名字
# 如果目标文件和当前文件在同一级目录下,则直接使用文件名即可
#file_name = "D:\\python-workspace\\python-base\\huan\\lesson_07\\code\\demo.txt"

file_name = "demo.txt"

# 在windows系统使用路径时,可以用/来代替\
# 或者可以使用\\来代替\
# 或者也可以使用原始字符串
#file_name = 'hello\\demo.txt'
#file_name = r'hello\demo.txt'

# 表示路径,可以使用..来返回上一级目录
#file_name = '../demo.txt'

# 如果目标文件距离当前文件比较远,此时可以使用绝对路径
# 绝对路径应该从磁盘的根目录开始书写
#file_name = "D:\\python-workspace\\python-base\\huan\\lesson_07\\code\\demo.txt"
open(file_name,"r",encoding='utf-8') # 打开file_name对应的文件

#f = open(file_name,"r",encoding='utf-8') # 打开file_name对应的文件

#print(f.read())

# print(f) # <_io.TextIOWrapper name='D:\\python-workspace\\python-base\\huan\\lesson_07\\code\\demo.txt' mode='r' encoding='utf-8'>

# with  as

# 对着 如下的 UTF-16BE 按左键 点击 move 找到UTF-8 按 Convert 则修改代码的格式

关闭文件

# 关闭文件

# 先打开文件
file_name = 'demo.txt'

# # 调用open()来打开文件
# file_obj = open(file_name)
#
# # 当我们获取了文件对象以后,所有的对文件的操作都应该通过对象来进行
# # 读取文件中的内容
# # read()方法,用来读取文件中的内容,他会将内容全部保存为一个字符串返回
# content = file_obj.read()
#
# print(content) # hello,Flie
#
# # 关闭文件
# # 调用close()方法来关闭文件
# file_obj.close()
#
# # file_obj.read()
# #     file_obj.read()
# # ValueError: I/O operation on closed file.

# with ... as 语句
with  open(file_name)  as file_obj:
    # 在with语句中可以直接使用file_obj来做文件操作
    # 此时这个文件只能在with中使用,一旦with结束则文件会自动close()
    print(file_obj.read())

# print(file_obj.read())
#     print(file_obj.read())
# ValueError: I/O operation on closed file.

file_name = 'hello12'

try:
    with open(file_name) as file_obj:
        print(file_obj.read())
except PermissionError:
    print('权限错误:[Errno 13]权限被拒绝')
#     with open(file_name) as file_obj:
# PermissionError: [Errno 13] Permission denied: 'hello'
except FileNotFoundError:
    print('文件不存在!')

文件读取

file_name = 'demo.txt'

# try :
#     # 调用open()来打开一个文件,可以将文件分成两种类型
#     # 一种,是纯文本文件(使用utf-8等编码编写的文本文件)
#     # 一种,是二进制文件(图片、mp3、PPT等这些文件)
#     # open()打开文件时,默认是以文本文件的形式打开的,但是open()默认的编码为None
#     #   所以处理文本文件时,必须要指定文件的编码
#     with open(file_name,encoding='utf-8') as file_obj:
#         # 通过read()来读取文件中的内容
#         # 如果直接调用read()它会将文本文件的左右内容全部读取出来
#         #   如果读取的文件较大的话,会一次性将文件的内容加载到内存中,容易导致内存泄漏
#         #   所以对于较大的文件,不要直接调用read()
#         # help(file_obj.read)
#         # read()可以直接接收一个size作为参数,该参数用来指定要读取的字符的数量
#         #   默认值为-1,他会读取文件中的所有字符
#         #   可以为size指定一个值,这样read()会读取指定数量的字符,
#         #       每一次读取都是从上次读取到的位置开始读取的
#         #       如果字符的数量小于size,则会读取剩余所有的
#         #       如果已经读取到了文件的最后了,则会返回’‘空串
#
#         # content = file_obj.read(-1)
#         content = file_obj.read(6)
#         content = file_obj.read(5)
#         content = file_obj.read(5)
#         print(content)
#         print(len(content))
# except FileNotFoundError:
#     print(f'{file_name}这个文件不存在!')

    # help(file_obj.read) 执行结果
    # Help on built-in function read:
    #
    # read(size=-1, /) method of _io.TextIOWrapper instance
    #     Read at most n characters from stream.
    #
    #     Read from underlying buffer until we have n characters or we hit EOF.
    #     If n is negative or omitted, read until EOF.

# 读取大文件的方式
file_name = 'demo.txt'

try :
    with open(file_name,encoding='utf-8') as file_obj:
        # 定义一个变量,来保存文件的内容
        file_content = ''
        # 定义一个变量,来指定每次读取的大小
        chunk = 100
        # 创建一个循环来读取文件内容
        while True:
            # 读取chunk大小的内容
            content = file_obj.read(chunk)
            # 检查是否读取到了内容
            if not content:
                # 内容已经读取完毕,退出循环
                break
            # 输出内容
            # print(content,end='') # hello,Flie
            file_content += content
            # print(file_content) # hello,Flie
except FileNotFoundError:
    print(f'{file_name}这个文件不存在!')

print(file_content)
import pprint

file_name = 'demo.txt'
with open(file_name,encoding='utf-8') as file_obj:
    # readline()
    # 该方法可以用来读取一行内容,每读取一次都会有一个换行
    # print(file_obj.readline())
    # print(file_obj.readline(),end='')
    # print(file_obj.read())

    # readlines()
    # 该方法用于一行一行的读取内容,他会一次性将读取到的内容封装到一个列表中返回
    r = file_obj.readlines()
    # print(r) # ['hello,Fliehello,Fliehello,Fliehello,Flie\n', 'hello,Fliehello,Fliehello,Flie\n', 'hello,Fliehello,Flie\n']
    # print(r[0])
    # print(r[1])
    # print(r[2])
    pprint.pprint(r[0])
    pprint.pprint(r[1])
    pprint.pprint(r[2])

    for t in file_obj:
        print(t)

文件的写入

file_name = 'demo.txt'

# 使用open()打开文件时必须要指定打开文件所要做的操作
# 如果不指定操作类型,则默认是 读取文件, 而读取文件时是不能向文件中写入的
# r : 表示只读的
# w : 表示是可写的,使用w来写入文件时,如果文件不存在会创建文件,如果文件存在则会截断文件
#       截断文件指的是删除原来文件中所有的内容
# a : 表示追加内容,如果文件不存在会创建文件,如果文件存在则会向文件中追加内容
# x : 用来新建文件,如果文件不存在则创建,存在则报错
# + : 为操作符增加功能
#   r+ : 即可读又可写,文件不存在会报错
#   w+ : 即可写又可读
#   a+ : 在追加的基础上可读
# with open(file_name,'w',encoding='utf-8') as file_obj:
# with open(file_name,'r+',encoding='utf-8') as file_obj:
with open(file_name,'x',encoding='utf-8') as file_obj:
    # write()来向文件中写入内容,
    # 如果操作的是一个文本文件的话,则write()需要传递一个字符串作为参数
    # 该方法会可以分多册向文件中写入内容
    # 写入完成以后,该方法会返回写入的字符串的个数
    file_obj.write('aaa\n')
    file_obj.write('bbb\n')
    file_obj.write('ccc\n')
    r = file_obj.write(str(123)+'123123\n') # 10
    r = file_obj.write('今天天气晴') # 5
    print(r)


# x : 用来创建新文件,文件存在即报错
#    with open(file_name,'x',encoding='utf-8') as file_obj:
# FileExistsError: [Errno 17] File exists: 'demo.txt'

文件

# file_name = r'C:\Users\hp\Pictures\蛋糕\1.jpg'
file_name = r'F:\Big data\大数据\尚硅谷MySQL入门到高级-宋红康版\视频\尚硅谷-14-最基本的SELECT...FROM结构.mp4'

# 读取模式
# t 读取文本文件(默认值)
# b 读取二进制文件

with open(file_name,'rb') as file_obj:
    # 读取文本文件时,size是以字符为单位的
    # 读取二进制文件时,size是以字节为单位
    # print(file_obj.read())

    # 将读取到的内容写出来
    # 定义一个新的文件
    new_name = 'aa.mp4'

    with open(new_name,'wb') as new_obj:
    # with open(new_name,'ab') as new_obj:
        # 定义每次读取的大小
        chunk = 1024 * 1024 # 1m

        while True:

            # 从已有的对象中读取数据
            content = file_obj.read(chunk)

            # 内容读取完毕,终止循环
            if not content:
                break

            # 将读取到的数据写入到新对象中
            new_obj.write(content)

读取文件位置

# with open('demo.txt','rb') as file_obj:
    # print(file_obj.read(10)) # b'aaa\r\nbbb\r\n'
    # print(file_obj.read()[0]) # 97
    # print(file_obj.read()) # b'aaa\r\nbbb\r\nccc\r\n123123123\r\n\xe4\xbb\x8a\xe5\xa4\xa9\xe5\xa4\xa9\xe6\xb0\x94\xe6\x99\xb4\r\nlorem'
#     # tell()方法用来查看当前读取的位置
#     print('当前读取到了 --->', file_obj.tell()) # 当前读取到了 ---> 10
#
#     # seek() 可以修改当前读取的位置
#     file_obj.seek(3)
#     file_obj.seek(3,0)
#     file_obj.seek(-3,2)
#     print('当前读取到了 --->',file_obj.tell())
#     # seek()需要两个参数
#     #   第一个 是要切换到的位置
#     #   第二个 计算位置的方式
#     #       可选值:
#     #           0 从头计算,默认值
#     #           1
#     #           2
#
#     print(file_obj.read(6))

# with open('demo.txt','rb',encoding='utf-8') as file_obj:
#     print(file_obj.read(10))
#     # tell()方法用来查看当前读取的位置
#     print('当前读取到了 --->', file_obj.tell()) # 当前读取到了 ---> 10
#
#     # seek() 可以修改当前读取的位置
#     # seek()在读取utf-8汉字的时候,需要注意一个字符=3个字节
#     file_obj.seek(3)
#     file_obj.seek(3,0)
#     file_obj.seek(-3,2)
#     print('当前读取到了 --->',file_obj.tell())
#     # seek()需要两个参数
#     #   第一个 是要切换到的位置
#     #   第二个 计算位置的方式
#     #       可选值:
#     #           0 从头计算,默认值
#     #           1
#     #           2
#
#     print(file_obj.read(6))

文件的其他操作

import os
from pprint import pprint

# os.listdir() 获取指定目录的目录结构
# 需要一个路径作为参数,会获取到该路径下的目录结构,默认路径为,当前目录
# 该访问会返回一个列表,目录中的一个文件(夹)的名字都是列表中的一个元素
r = os.listdir()
r = os.listdir('..')
# ['code', 'demo.txt']

# pprint(r)
# ['aa.jpg',
#  'aa.mp4',
#  'demo.txt',
#  'eight文件的写入.py',
#  'elven文件的其他操作.py',
#  'five关闭文件.py',
#  'four打开文件.py',
#  'hello',
#  'nine文件.py',
#  'one异常.py',
#  'seven文件读取.py',
#  'six文件的读取.py',
#  'ten读取文件的位置.py',
#  'three抛出异常.py',
#  'two异常对象.py']

# os.getcwd() # 获取当前所在的目录
# r = os.getcwd()
# pprint(r)
# 'D:\\python-workspace\\python-base\\huan\\lesson_07\\code'

# os.chdir() # 切换当前所在的目录,作用相当于cd
# os.chdir('c:/')
# r = os.getcwd() # 'c:\\'

# 创建目录
# os.mkdir('aaa') # 在当前目录下创建一个名字为aaa的目录

# 删除目录6325478+3
# os.rmdir('aaa')

# 删除文件
# os.remove('aa.jpg')

# 重命名文件
# os.rename('旧名字','新名字') # 可以对一个文件进行重命名,也可以用来移动一个文件
# os.rename('aa.mp4','123.mp4')
# os.rename('123.mp4','../123.mp4')
# pprint(r)

你可能感兴趣的:(Python,python,学习,开发语言)