打开文件
- Python中无论是从文件中读还是吧内容写到文件中,首先都需要打开文件,使用open函数。
open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True) Open file and return a stream. Raise OSError upon failure.
只有file参数是必须传都,其他都是默认值;最简单的例子如下:
file_name="/Users/xulei/PycharmProjects/test/demodoc.txt"
f=open(file_name)
print(type(f))
# <class '_io.TextIOWrapper'>
- open常用参数介绍:
1,file: 必需,文件路径(相对或者绝对路径)。
2,mode: 可选,文件打开模式
3,buffering: 设置缓冲
4,encoding: 一般使用utf8
5,errors: 报错级别
6,newline: 区分换行符 - 其中最需要理解的是文件的打开方式,就是把文件以什么样的形式打开,是写呢?读呢?还是以二进制模式打开呢?下面表格自由组合:
打开模式 | 执行操作 |
---|---|
‘r’ | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
‘w’ | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑。即原有内容会被删除。如果该文件不存在,创建新文件。 |
‘x’ | 写模式,新建一个文件,如果该文件已存在则会报错。 |
‘a’ | 追加模式,打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
‘b’ | 以二进制模式打开文件。一般用于非文本文件,如:图片。 |
‘t’ | 以文本模式打开(默认)。一般用于文本文件,如:txt。 |
‘+’ | 可读写模式(可添加到其它模式中使用 |
- open文件成功后返回一个文件对象,如果打开失败会出现OSError读错误。
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt')
print(f)
# <_io.TextIOWrapper name='将进酒.txt' mode='r' encoding='cp936'>
for each in f:
print(each)
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
文件读取
- f.close() 文件打开使用后要关闭掉.被关闭掉文件不能被读取,否则出现ValueEror错误。
- f.read([size]) 从文件中读自定字符数,为给定参数或者为负数,则读去所有;
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt')
value =f.read(50)
print(value)
f.close()
# Hello world I am. Xulei
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高
- f.readline() 读整行 包括换行符‘\n’
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt')
a=1
while a<4:
print(f.readline())
a+=1
f.close()
# Hello world I am. Xulei
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
- f.readlines() 与上面readline不同的是这个是读取所有多行(EOF为结束符),返回列表由for in循环处理:
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt')
lines=f.readlines()
print(lines)
# ['Hello world I am. Xulei\n', '君不见,黄河之水天上来,奔流到海不复回。\n', '君不见,高堂明镜悲白发,朝如青丝暮成雪。\n', '人生得意须尽欢,莫使金樽空对月。\n', '天生我材必有用,千金散尽还复来。\n', '烹羊宰牛且为乐,会须一饮三百杯。\n', '岑夫子,丹丘生,将进酒,杯莫停。\n', '与君歌一曲,请君为我倾耳听。\n', '钟鼓馔玉不足贵,但愿长醉不复醒。\n', '古来圣贤皆寂寞,惟有饮者留其名。\n', '陈王昔时宴平乐,斗酒十千恣欢谑。\n', '主人何为言少钱,径须沽取对君酌。\n', '五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。']
for each in lines:
each.strip()
print(each)
f.close()
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
- f.tell()返回当前文件指针位置。
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt','r')
lines=f.read(30)
print(lines)
print(f.tell())#42
# Hello world I am. Xulei
# 君不见,黄河
# 42
- f.seek(offset,start) 移动指针到指定位置。参数一:偏移量;参数二:可选,移动的起点,0-文件头,1-当前位置,2-文件末尾,默认0;
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt','r')
f.seek(8,0)
print(f.tell())
print(f.readline())
# 8
# rld I am. Xulei
- f.write(str) 向文件中写入制定字符串,返回的是写入的字符串的长度。记得文件打开格式不能是r只读,应该是w或者w+或者a追加的形式打开:
f = open('/Users/xulei/PycharmProjects/test/testdoc.txt','r')
print(f.readlines())
# ['我是个大水啊哥\n', '我喜欢python']
f = open('/Users/xulei/PycharmProjects/test/testdoc.txt','a')
f.write("学习真开心呀!")
f = open('/Users/xulei/PycharmProjects/test/testdoc.txt','r')
print(f.readlines())
# ['我是个大水啊哥\n', '我喜欢python学习真开心呀!']
f.close()
在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容的。
- 如果文件打开模式带b,那写入文件内容时,str(参数)要用encode方法转为bytes形式(在字符串前面带上字母b),否则报错:TypeError: a bytes-like object is required, not ‘str’。
str = '...'
# 文本 = Unicode字符序列
# 相当于 string 类型
str = b'...'
# 文本 = 八位序列(0到255之间的整数)
# 字节文字总是以‘b’或‘B’作为前缀;它们产生一个字节类型的实例,而不是str类型。
# 相当于 byte[]
【举个例子】
f = open('/Users/xulei/PycharmProjects/test/将进酒.txt', 'r+')
str = '\n 作什么者:DMULLQ'
f.seek(0, 2)
line = f.write(str)
f.seek(0, 0)
for each in f:
print(each)
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
# 作什么者:DMULLQ
f.close()
- f.writelines(seq)向文件中写入一个序列字符串列表。常常带上‘ /n ’
# 覆盖追加的形式写进去的,把之前的内容给覆盖掉了
f = open('/Users/xulei/PycharmProjects/test/testdoc.txt','w+')
seq = ['小马的程序人生\n', '老马的程序人生']
f.writelines(seq)
f.seek(0, 0) # 写完后的指针回到文件头
for each in f:
print(each)
f.close()
# 小马的程序人生
# 老马的程序人生
OS模块
- OS模块是干啥呢的?不同操作系统的对地成文件系统的访问工作原理是不一样的,为了兼容性。OS模块,会帮助选择当前系统下最合适的模块调用。
- os.getcwd()用于返回当前工作目录。
- os.chdir(path)用于改变当前工作目录到指定的路径。
比如我开发环境在path路径下的,所有的操作都是在path目录下的,当我程序被移植到一个陌生的系统了。我path路径是不是应该要被修改。但是我不知道被移植到了哪里,OS系统能给你自动独处当前系统的当前路径,然后chdir方法来修改path的值,让程序继续运行
import os
path = '/Users/xulei/PycharmProjects/test' #程序运行目录
print("当前工作目录 : %s" % os.getcwd())
# 当前工作目录 : /Users/xulei/PycharmProjects/untitled/Test_Demo
os.chdir(path)
print("目录修改成功 : %s" % os.getcwd())
# 目录修改成功 : /Users/xulei/PycharmProjects/test
- listdir (path=’.’)返回path指定的文件夹包含的文件或文件夹的名字的列表。
import os
dirs = os.listdir()
for item in dirs:
print(item)
# /usr/bin/python3 /Users/xulei/PycharmProjects/untitled/Test_Demo/demo1.py
# Hello_wold.py
# __pycache__
# demo1.py
# const.py
- os.mkdir(path) 创建单层目录,如果该目录已存在抛出异常(通常都会os.path.isdir(dir) is False :来判断该目录是否存在)
import os
if os.path.isdir(r'.\b') is False:
os.mkdir(r'.\B')
os.mkdir(r'.\B\A')
dirs = os.listdir()
for item in dirs:
print(item)
#/usr/bin/python3 /Users/xulei/PycharmProjects/untitled/Test_Demo/demo1.py
# Hello_wold.py
# .\B\A
# __pycache__
# demo1.py
# const.py
# .\B
- os.makedirs(path)用于递归创建多层目录,如果该目录已存在抛出异常
import os
os.makedirs(r'\DMULLQ\SANSHI')
dirs = os.listdir()
for item in dirs:
print(item)
#/usr/bin/python3 /Users/xulei/PycharmProjects/untitled/Test_Demo/demo1.py
# Hello_wold.py
# .\B\A
# __pycache__
# demo1.py
# \DMULLQ\SANSHI
# const.py
# .\B
- listdir (path=’.’)返回path指定的文件夹包含的文件或文件夹的名字的列表
import os
dirs = os.listdir()
for item in dirs:
print(item)
- os.remove(path)用于删除指定路径的文件。如果指定的路径是一个目录,将抛出 OSError。
- os.rmdir(path)用于删除单层目录。仅当这文件夹是空的才可以, 否则, 抛出 OSError。
- os.removedirs(path)递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常。???跟rmdir没什么区别啊??
import os
os.rmdir(".\B")
dirs = os.listdir()
for item in dirs:
print(item)
# /usr/bin/python3 /Users/xulei/PycharmProjects/untitled/Test_Demo/demo1.py
# Hello_wold.py
# .\B\A
# __pycache__
# demo1.py
# \DMULLQ\SANSHI
# const.py
- os.rename(src, dst)方法用于命名文件或目录,从 src 到 dst,如果 dst 是一个存在的目录, 将抛出 OSError。
import os
print("目录为: %s" % os.listdir(os.getcwd()))
os.rename("test.txt", "test2.txt")
print("重命名成功。")
print("目录为: %s" % os.listdir(os.getcwd()))
- os.system(command)运行系统的shell命令(将字符串转化成命令)
import os
path = os.getcwd() + '\\a.py'
a = os.system(r'python %s' % path)
os.system('calc') # 打开计算器
1,os.curdir指代当前目录(.)
2,os.pardir指代上一级目录(…)
3,os.sep输出操作系统特定的路径分隔符(win下为\,Linux下为/)
4,os.linesep当前平台使用的行终止符(win下为\r\n,Linux下为\n)
5,os.name指代当前使用的操作系统(包括:‘mac’,‘nt’)
import os
print(os.curdir) # .
print(os.pardir) # ..
print(os.sep) # \
print(os.linesep)
print(os.name) # nt
1,os.path.basename(path)去掉目录路径,单独返回文件名
2,os.path.dirname(path)去掉文件名,单独返回目录路径
3,os.path.join(path1[, path2[, …]])将 path1,path2 各部分组合成一个路径名
4,os.path.split(path)分割文件名与路径,返回(f_path,f_name)元组。如果完全使用目录,它会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在。
5,os.path.splitext(path)分离文件名与扩展名,返回(f_path,f_name)元组。
import os
# 返回文件名
print(os.path.basename(r'C:\test\lsgo.txt')) # lsgo.txt
# 返回目录路径
print(os.path.dirname(r'C:\test\lsgo.txt')) # C:\test
# 将目录和文件名合成一个路径
print(os.path.join('C:\\', 'test', 'lsgo.txt')) # C:\test\lsgo.txt
# 分割文件名与路径
print(os.path.split(r'C:\test\lsgo.txt')) # ('C:\\test', 'lsgo.txt')
# 分离文件名与扩展名
print(os.path.splitext(r'C:\test\lsgo.txt')) # ('C:\\test\\lsgo', '.txt')
1,os.path.getsize(file)返回指定文件大小,单位是字节。
2,os.path.getatime(file)返回指定文件最近的访问时间
3,os.path.getctime(file)返回指定文件的创建时间
4,os.path.getmtime(file)返回指定文件的最新的修改时间
5,浮点型秒数,可用time模块的gmtime()或localtime()函数换算
import os
import time
file = r'.\lsgo.txt'
print(os.path.getsize(file)) # 30
print(os.path.getatime(file)) # 1565593737.347196
print(os.path.getctime(file)) # 1565593737.347196
print(os.path.getmtime(file)) # 1565593797.9298275
print(time.gmtime(os.path.getctime(file)))
# time.struct_time(tm_year=2019, tm_mon=8, tm_mday=12, tm_hour=7, tm_min=8, tm_sec=57, tm_wday=0, tm_yday=224, tm_isdst=0)
print(time.localtime(os.path.getctime(file)))
# time.struct_time(tm_year=2019, tm_mon=8, tm_mday=12, tm_hour=15, tm_min=8, tm_sec=57, tm_wday=0, tm_yday=224, tm_isdst=0)
1,os.path.exists(path)判断指定路径(目录或文件)是否存在
2,os.path.isabs(path)判断指定路径是否为绝对路径
3,os.path.isdir(path)判断指定路径是否存在且是一个目录
4,os.path.isfile(path)判断指定路径是否存在且是一个文件
5,os.path.islink(path)判断指定路径是否存在且是一个符号链接
6,os.path.ismount(path)判断指定路径是否存在且是一个悬挂点
7,os.path.samefile(path1,path2)判断path1和path2两个路径是否指向同一个文件
import os
print(os.path.ismount('D:\\')) # True
print(os.path.ismount('D:\\Test')) # False
序列化和反序列化
__Python 的 pickle 模块实现了基本的数据序列和反序列化。__
1,通过 pickle 模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
2,通过 pickle 模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
__pickle模块中最常用的函数为:__
pickle.dump(obj, file, [,protocol]) 将obj对象序列化存入已经打开的file中。
1,obj:想要序列化的obj对象。
2,file:文件名称。
3,protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
__pickle.load(file) 将file中的对象序列化读出。__
file:文件名称。
import pickle
dataList = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
dataDic = {0: [1, 2, 3, 4],
1: ('a', 'b'),
2: {'c': 'yes', 'd': 'no'}}
# 使用dump()将数据序列化到文件中
fw = open(r'.\dataFile.pkl', 'wb')
# Pickle the list using the highest protocol available.
pickle.dump(dataList, fw, -1)
# Pickle dictionary using protocol 0.
pickle.dump(dataDic, fw)
fw.close()
# 使用load()将数据从文件中序列化读出
fr = open('dataFile.pkl', 'rb')
data1 = pickle.load(fr)
print(data1)
data2 = pickle.load(fr)
print(data2)
fr.close()
# [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
# {0: [1, 2, 3, 4], 1: ('a', 'b'), 2: {'c': 'yes', 'd': 'no'}}