一、永久存储
1.文件的基础操作
(1)open():open( file , mode ' r ' , buffering = -1 , encoding = None , errors = None , newline = None , closed = True , opener = None ),文件的打开模式如下表
(2)文件对象方法 (Python拥有垃圾回收机制,会在文件对象的引用计数降至0的时候自动关闭文件,不同于C语言可能会造成内存泄露甚至内存溢出)
# 文件读取
# f.read()
# 以二进制形式打开指定文件,该文件编码格式为 utf-8
# r"" 表示使用原始字符串字面量来指定文件路径,避免在字符串中需要对反斜杠进行额外的转义
f = open(r"test.txt", "rb+")
# 如果提供一个正整数参数size,它将尝试读取最多size个字符(如果文件以文本模式打开)
# 或字节(如果文件以二进制模式打开),并返回读取到的内容
tests = f.read()
print(tests)
print('\n抓换后:\n'tests.decode('utf-8'))
f.close()
# f.readlines()
# 从文件中读取单独的一行(文本格式)
# 二进制格式打开的文件,以'\n'作为读取一行的标志
f = open(r"test.txt")
tests = f.readlines() # 返回一个列表,包含文件的所有内容
print(tests)
f.close()
# f.readline
# 该函数类似不指定size参数的read()函数,但返回的是字符串列表
f = open(r"test.txt")
while 1:
test = f.readline() # 一次读取一行,避免大文件读取内存溢出
if test:
print(type(test), test)
else:
break
f.close()
# 文件写入
# f.write()
f = open(r"test.txt","w")
str = "good job\n"
f.write(str) # 返回写入字符的长度
f.close()
# f.writelines()
# 写入一个字符串列表序列,手动\n换行
f = open(r"test.txt","a")
strs = ["good job\n", "be relax\n"]
f.writelines(strs)
f.close()
# 文件定位
f = open(r"test.txt")
f.read(5) # 读取文件指针所在位置后5个字节的内容
f.tell() # 返回当前文件内指针所指的位置
# seek(offset, from_what) from_what 为0表示开头,为1表示当前位置,为2表示文件结尾
# offset非0时,文件需以二进制形式打开
# 防止收到文本编码和换行符转换的影响,确保文件指针的移动和字节偏移量的计算是准确的
f.seek(0,0) # 将文件指针移到文件起始位置
f.close()
2.文件相关模块
(1)OS 模块:Operating System,操作系统,关于文件/目录常用的函数及其使用方法如下
# getcwd():获得应用程序当前的工作目录
>>> import os
>>> os.getcwd
# chdir(path):改变当前工作目录
>>> os.chdir("C:\\")
>>> os.getcwd()
# listdir(path='.'):列举当前目录下的文件和子目录
# path默认为'.',表示当前目录,'..'表示上级目录
>>> os.listdir('.')
>>> os.listdir("D:\\")
# mkdir(path):创建文件夹,若该文件夹存在则抛出 FileExistsError 异常
>>> os.mkdir("test")
>>> os.listdir()
# makedirs(path):创建多层目录
>>> os.makedirs(r".\a\b\c")
# remove(path):删除指定文件
>>> os.remove("test.txt")
# rmdir(path):删除指定目录
>>> os.rmdir("test")
# removedirs(path):删除多层目录
>>> os.removedirs(r"a\b\test")
# rename(old,new):重命名文件或文件夹
>>> os.rename("text","texttext")
>>> os.rename("text.txt","texttext.txt")
# system("command"):提供操作系统中的小工具,例如 calc 代表计算器
>>> os.system("calc")
# walk(top):遍历top参数指定路径下的所有子目录,并将结果返回为一个三元组(路径,[包含目录],[包含文件])
>>> for i in os.walk("text"):
... print(i)
以下支持所有平台,支持路径操作中常用到的一些定义
(2)OS.path 模块:可以完成针对路径名的操作,常用的函数及其使用方法如下
# basename(path) 和 dirname(path):分别为用户获得文件名和路径名
>>> import os
>>> os.path.dirname(r"a\b\test.txt")
'a\\b'
>>> os.path.basename(r"a\b\test.txt")
'test.txt'
# join(path1[,path2[,...]]):用于将路径名和文件名组合成一个完整的路径,不同于 BIF 中的 join() 函数
>>> os.path.join(r"D:\a\b","test.txt")
'D:\\a\\b\\test.txt'
# split(path) 和 splitext(path):前者分割路径和文件名(若无文件名,完全使用目录,则将最后一个目录名分离,且不会判断文件或目录是否存在),后者分割文件名和扩展名
>>> os.path.split(r"a\b\test.txt")
('a\\b','test.txt')
>>> os.path.splitext(r"a\b\test.txt")
('a\\b\\test.txt','.txt')
# getsize(file):用于获取文件的尺寸,返回值以字节为单位
>>> os.path.getsize("test.txt")
# getatime(file)、getctime(file)和getmtime():分别获得文件的最近访问时间、创建时间和修改时间,返回值为浮点型秒数,可 import time 来用 time 模块的 gmtime() 或 localtime 函数进行换算
以下函数返回 True 或 False
(3)pickle 模块:可将几乎所有 Python 对象都转化为二进制的形式存放,该过程称为pickling
>>> import pickle
>>> test_list = [a, 1.23, '嘿嘿', ['the other one']]
>>> picTest_file = open('D:\\test.pkl', 'wb')
# 保存数据可用 dump() 方法
>>> pickle.dump(test_list, picTest_file)
>>> picTest_file.close()
而从二进制形式转换为对象的过程称为 unpickling
>>> import pickle
>>> picTest_file = open('D:\\test.pkl', 'rb')
# 加载数据可用 load() 方法
>>> my_list = pickle.load(picTest_file)
>>> print(my_list)
- dumps():将 Python 中的对象序列化成二进制对象,并返回;
- loads():读取给定的二进制对象数据,并将其转换为 Python 对象
(注:pickle 不支持并发地访问持久性对象,可使用ZODB,专门存储和管理任意复杂的python中的对象数据,并支持事物操作和并发控制,是一个健壮的、多用户的面向对象的数据库系统。)
(4)其他模块:
fileinput 模块:通过 input() 函数,能同时打开指定的多个文件,还可以逐个读取这些文件中的内容。fileinput.input(file=('a.txt', 'b.txt')) 可直接通过 for 循环按次读取多个文件中的数据。
(注:input() 函数不能打开指定文件的编码格式,即除了二进制方式读取,文件编码格式必须和当前操作系统的编码格式相同,否则提示 UnicodeDecodeError 错误)
linecache 模块、pathlib 模块、fnmatch 模块、tempfile 模块等...
二、异常处理
1.常见异常
例:FileNotFoundError...
# 正确语句
>>> file_name = input("请输入要打开的文件名:")
>>> f = open(file_name,'r')
>>> print("文件的内容是:")
>>> for each_line in f:
print(ecah_line)
# 当输入不存在的文件名时,系统报错
# FileNotFoundError...
(1)AssertionError:断言语句(assert)失败,当 assert xxx 中 assert 关键字后面的 xxx 条件为假,程序将停止并抛出 AssertionError 异常
(2)AttributeError:尝试访问未知的对象属性,当试图访问的对象属性不存在时抛出 AttributeError 异常
(3)IndexError:索引超出序列的范围
(4)KeyError:字典中查找一个不存在的关键字,建议使用 dict.get() 方法 ( dict("不存在的key") )
(5)NameError:尝试访问一个不存在的变量 (直接输入不存在变量名回车,则报错)
(6)OSError:操作系统产生的异常,像 FileNotFoundError 就是 OSError 的子类
(7)SyntaxError:Python 的语法错误
(8)TypeError:不同类型间的无效操作,类型不同的对象无法进行相互计算,否则抛出 TypeError 异常
(9)ZeroDivisionError:除数为零异常
2.检测和处理异常
(1)try-except 语句(try 语句范围内一旦出现异常,剩下的语句将不会被执行)
# 文件打开异常的优化
>>> try:
... f = open('某个不存在的文件.txt')
... print(f.read())
... f.close()
# 针对不同异常设置多个 except
... except OSError as reason:
... print('文件打开出错!\n错误原因为:' + str(reason))
... except TypeError as reason:
... print('文件类型出错!\n错误原因为:' + str(reason))
# except 后面可以跟着多个异常,可对其进行统一处理
... except (OSError, TypeError):
... print('文件出错!\n错误原因为:' + str(reason))
(2)try-finally 语句:
# try 语句中没有出现任何运行时错误,则会跳过 except 语句块执行 finally 语句块的内容
# 若出现异常,则会先执行 except 语句块的内容,再执行 finally 语句块的内容
# finally 语句块中的内容就是确保无论如何都将被执行的内容
>>> try:
... f = open('某个存在的文件.txt')
... print(f.read())
... sum = 1 + '1'
... except:
... print('出错!')
... finally:
... f.close()
(3)raise 语句:
# raise 语句能自定义抛出异常
>>> raise ZeroDivisionError("除数不能为零!")
(4)with 语句:
# with 语句会自动帮助关闭文件
>>> try:
... with open('data.txt', 'w') as f:
... for each_line in f:
... print(each_line)
... except OSError as reason:
... print('出错啦:' + str(reason))