os 模块
mkdir : 创建文件夹
remove : 删除文件
rmdir : 删除文件夹
isfile : 判断是否是文件
文件的操作
操作文件内部的内容
#1.打开一个文件 open
f = open("测试.py" , 'w')
# 2. 写入操作
f.write("print(hello world)")
#3.关闭
f.close()
seek(‘跳过的字符数’ , x) x用的值如下 : 0开头 1光标的当前位置 2结尾
打开
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
open(文件路径,访问模式)
示例如下:
f = open('test.txt', 'w')
f.write("hello")
f.seek(0 , 2) #0代表跳过多少字节,,2代表光标放在末尾
文件路径
文件的路径分为相对路径和绝对路径两种。
绝对路径:指的是绝对位置,完整的说明了文件的详细位置,文件层级啥的(比如收快递的地址)
相对路径:是从当前文件所在的文件夹开始的路径。(比如顺丰同城快递的收货地址)
访问模式
下面的b表示二进制
r 只读,默认文本文件 ,打开后光标(指针)在头部,如果文件不存在,会报错,是open的默认打开模式
w 只写,如果文件不存在,就会直接创建,存在,就会直接覆盖
write 是写入,只会写一次(就是不停的覆盖)
a append追加 写入,如果文件存在,光标放在内容最后,追加写入,如果文件不存在,就创建文件并写入
没有a就没有追加
rb 最常用于 不确定操作的文件是不是文本文件
r+ 可读可写,光标(文件指针)始终在开头.不能追加.会且仅覆盖输入的字节数,输入十个字节就覆盖十个,输入二十个字节就覆盖二十个字节
w+ 可读可写,文件存在就覆盖,文件不存在,就创建文件 (可使用read(num))
但读的时候,光标在最后,读出来的是空白,所以要读的话就要用seek(0,0)方法把贯标弄到最前面, 第二个0表示光标在开头
a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
seek 指定光标位置
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
ab+ 以二进制格式打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
复制视频用rb 和wb ,并且使用最多的为rb,wb使用要小心,rb可以随便使用
读一个文件(read)
使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
num一般使用1024,表示1kb, 或者是用1024的整数来输出,虽然慢,但是在输出打打文件的时候,电脑不会卡死
demo: 新建一个文件file_read_test.py,向其中写入如下代码:
注意:
如果用open打开文件时,如果使用的"r",那么可以省略 open(‘test.txt’)
f = open('test.txt', 'r')
content = f.read(5) # 最多读取5个数据
print(content)
print("-"*30) # 分割线,用来测试
content = f.read() # 从上次读取的位置继续读取剩下的所有的数据
print(content)
f.close() # 关闭文件,这个可是个好习惯哦
读数据(readline)
readline只用来读取一行数据。读这一行的第几个值
f = open('test.txt', 'r')
content = f.readline()
print("1:%s" % content)
content = f.readline()
print("2:%s" % content)
f.close()
读数据(readlines)
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行为列表的一个元素。
f = open('test.txt', 'r')
content = f.readlines()
print(type(content))
for temp in content:
print(temp)
f.close()
写一个文件(write)
使用write()可以完成向文件写入数据
demo: 新建一个文件 file_write_test.py,向其中写入如下代码:
运行之后会在file_write_test.py文件所在的路径中创建一个文件test.txt,并写入内容,运行效果显示如下:
注意:
如果文件不存在,那么创建;如果存在那么就先清空,然后写入数据
复制文件
复制一个多媒体文件
file_name = "测试.py"
f = open ("file_name",'r')#需要在当前文件夹中弄一个这个py文件
f2 = open(f"路径{file_name}",'w') #f2为复制的文件的路径
contents = f.readlines()
for i in contents:
f2.write(i)
f.close
f2.close
#复制文件
file_name = "目标文件.py"
f = open(file_name, 'r') # r只读
f2 = open(f"具体路径{file_name}", 'w') #具体路径前面可以加上r,就取消了转义字符
#w只写,,会覆盖,
#创建对象
contents = f.readlines()
#吧目标文件中的东西循环出来,并且循环一次写到新文件一次
for i in contents:
f2.write(i)
f.close()
f2.close()
指针定位
tell() 方法用来显示当前指针的位置
f = open('test.txt')
print(f.read(10)) # read 指定读取的字节数
print(f.tell()) # tell()方法显示当前文件指针所在的文字
f.close()
seek(offset,whence) 方法用来重新设定指针的位置。
-
offset:表示偏移量(跳过几个字节(字符))
-
whence:只能传入012中的一个数字。
- 0表示从文件头开始
- 1表示从当前位置开始
- 2 表示从文件的末尾开始
f = open('test.txt','rb') # 需要指定打开模式为rb,只读二进制模式
print(f.read(3))
print(f.tell())
f.seek(2,0) # 从文件的开头开始,跳过两个字节
print(f.read())
f.seek(1,1) # 从当前位置开始,跳过一个字节
print(f.read())
f.seek(-4,2) # 从文件末尾开始,往前跳过四个字节
print(f.read())
f.close()
如何与excel交互,csv方法
CSV文件
CSV文件:Comma-Separated Values,中文叫逗号分隔值或者字符分割值,其文件**以纯文本的形式存储表格数据。**可以把它理解为一个表格,只不过这个表格是以纯文本的形式显示的,单元格与单元格之间,默认使用逗号进行分隔;每行数据之间,使用换行进行分隔。
name,age,score
zhangsan,18,98
lisi,20,99
wangwu,17,90
jerry,19,95
Python中的csv模块,提供了相应的函数,可以让我们很方便的读写csv文件。
CSV文件的写入
import csv
# 以写入方式打开一个csv文件
file = open('test.csv','w')
# 调用writer方法,传入csv文件对象,得到的结果是一个CSVWriter对象
writer = csv.writer(file)
# 调用CSVWriter对象的writerow方法,一行行的写入数据
writer.writerow(['name', 'age', 'score'])
# 还可以调用writerows方法,一次性写入多行数据
writer.writerows([['zhangsan', '18', '98'],['lisi', '20', '99'], ['wangwu', '17', '90'], ['jerry', '19', '95']])
file.close()
CSV文件的读取
import csv
# 以读取方式打开一个csv文件
file = open('test.csv', 'r')
# 调用csv模块的reader方法,得到的结果是一个可迭代对象
reader = csv.reader(file)
# 对结果进行遍历,获取到结果里的每一行数据
for row in reader:
print(row)
file.close()
内存写入数据
除了将数据写入到一个文件以外,我们还可以使用代码,将数据暂时写入到内存里,可以理解为数据缓冲区。Python中提供了StringIO和BytesIO这两个类将字符串数据和二进制数据写入到内存里。
tringIO
要导包,StringIO可以将字符串写入到内存中,像操作文件一下操作字符串。
只不过是暂时写入内存,关掉pychar 这个就没了,读不到了
注意调用getvalue,需要调用getvalue()方法才能获取到写入到内存中的数据
from io import BytesIO
b = BytesIO()
b.write("你好".encode('utf-8'))
print(b.getvalue().decode('utf-8'))
b.close()
from io import StringIO
# 创建一个StringIO对象
f = StringIO()
# 可以像操作文件一下,将字符串写入到内存中
f.write('hello\r\n')
f.write('good')
# 使用文件的 readline和readlines方法,无法读取到数据
# print(f.readline())
# print(f.readlines())
# 需要调用getvalue()方法才能获取到写入到内存中的数据
print(f.getvalue())
f.close()
BytesIO
如果想要以二进制的形式写入数据,可以使用BytesIO类,它的用法和StringIO相似,只不过在调用write方法写入时,需要传入二进制数据。
from io import BytesIO
f = BytesIO()
f.write('你好\r\n'.encode('utf-8'))
f.write('中国'.encode('utf-8'))
print(f.getvalue())
f.close()
序列化和反序列化
建议使用pickle方法
通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个对象(例如列表、字典、元组等),就无法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里。
设计一套协议,按照某种规则,把内存中的数据转换为字节序列,保存到文件,这就是序列化,反之,从文件的字节序列恢复到内存中,就是反序列化。
Python中提供了JSON和pickle两个模块用来实现数据的序列化和反序列化。
JSON模块
不可以跨平台
JSON(JavaScriptObjectNotation, JS对象简谱)是一种轻量级的数据交换格式,它基于 ECMAScript 的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。JSON的本质是字符串!
使用JSON实现序列化
JSON提供了dump和dumps方法,将一个对象进行序列化。
dumps方法的作用是把对象转换成为字符串,它本身不具备将数据写入到文件的功能。
import json
file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
# file.write(names) 出错,不能直接将列表写入到文件里
# 可以调用 json的dumps方法,传入一个对象参数
result = json.dumps(names)
# dumps 方法得到的结果是一个字符串
print(type(result)) # <class 'str'>
# 可以将字符串写入到文件里
file.write(result)
file.close()
dump方法可以在将对象转换成为字符串的同时,指定一个文件对象,把转换后的字符串写入到这个文件里。
import json
file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
# dump方法可以接收一个文件参数,在将对象转换成为字符串的同时写入到文件里
json.dump(names, file)
file.close()
JSON模块
JSON(JavaScriptObjectNotation, JS对象简谱)是一种轻量级的数据交换格式,它基于 ECMAScript 的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。JSON的本质是字符串!
使用JSON实现序列化
JSON提供了dump和dumps方法,将一个对象进行序列化。
dumps方法的作用是把对象转换成为字符串,它本身不具备将数据写入到文件的功能。
import json
file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
# file.write(names) 出错,不能直接将列表写入到文件里
# 可以调用 json的dumps方法,传入一个对象参数
result = json.dumps(names)
# dumps 方法得到的结果是一个字符串
print(type(result)) # <class 'str'>
# 可以将字符串写入到文件里
file.write(result)
file.close()
Copy
dump方法可以在将对象转换成为字符串的同时,指定一个文件对象,把转换后的字符串写入到这个文件里。
import json
file = open('names.txt', 'w')
names = ['zhangsan', 'lisi', 'wangwu', 'jerry', 'henry', 'merry', 'chris']
# dump方法可以接收一个文件参数,在将对象转换成为字符串的同时写入到文件里
json.dump(names, file)
file.close()
Copy
注意:如果是一个空对象,调用dumps方法转换成为一个JSON对象,得到的结果是null(JS里的空对象)
json.dumps(None) # null
使用JSON实现反序列化
使用loads和load方法,可以将一个JSON字符串反序列化成为一个Python对象。
loads方法需要一个字符串参数,用来将一个字符串加载成为Python对象。
loads需要先把对象读出来(字符串)才能反序列化,load可以直接反序列化
import json
# 调用loads方法,传入一个字符串,可以将这个字符串加载成为Python对象
result = json.loads('["zhangsan", "lisi", "wangwu", "jerry", "henry", "merry", "chris"]')
print(type(result)) # <class 'list'>
load方法可以传入一个文件对象,用来将一个文件对象里的数据加载成为Python对象。
import json
# 以可读方式打开一个文件
file = open('names.txt', 'r')
# 调用load方法,将文件里的内容加载成为一个Python对象
result = json.load(file)
print(result)
file.close()
pickle模块
可以跨平台
和json模块类似,pickle模块也有dump和dumps方法可以对数据进行序列化,同时也有load和loads方法进行反序列化。区别在于,json模块是将对象转换成为字符串,而pickle模块是将对象转换成为二进制。
pickle模块里方法的使用和json里方法的使用大致相同,需要注意的是,pickle是将对象转换成为二进制,所以,如果想要把内容写入到文件里,这个文件必须要以二进制的形式打开。
import pickle
f = open("对象2.txt", 'wb')
per_dict = {'name': '李四', 'age': 18}
pickle.dump(per_dict, f)
f.close()# 这句代码很重要,一定要写,每次打开都要关闭
f2 = open("对象2.txt", 'rb')
per = pickle.load(f2)
print(per)
f2.close()
pickle序列化自定义对象
import pickle
class Person(object):
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def __str__(self):
return f"{self.name}--{self.sex}--{self.age}"
f = open("对象3.txt", "wb") #这里的b表示二进制
per = Person('张三', '男', 18)
pickle.dump(per, f)
f.close()
f2 = open("对象3.txt", "rb")
print(pickle.load(f2))
序列化和反序列化
JSON提供了dump和dumps方法,将一个对象进行序列化。
pickle模块也有dump和dumps方法可以对数据进行序列化,同时也有load和loads方法进行反序列化
推荐使用load方法.因为 oads都是对字符串进行操作,需要先把目标的值先输出位字符串,才可以操作
通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个对象(例如列表、字典、元组等),就无法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里。
设计一套协议,按照某种规则,把内存中的数据转换为字节序列,保存到文件,这就是序列化,反之,从文件的字节序列恢复到内存中,就是反序列化。
Python中提供了JSON和pickle两个模块用来实现数据的序列化和反序列化。
# 序列化是为了对咱们的对象进行存储到文件的操作
# 反序列化就是将文件中的内容读取出来的操作
import json
class MyObj(json.JSONEncoder):
def default(self, o):
return o.__dict__
class Person(object):
def __init__(self, name, sex, age):
self.name = name
self.sex = sex
self.age = age
def __str__(self):
return f"{self.name}--{self.sex}--{self.age}"
f = open('对象.txt', 'w')
p = Person("john", "男", 23)
result = json.dumps(p, cls=MyObj)
f.write(result)
f.close()
f2 = open('对象.txt', 'r')
read = f2.read()
per = json.loads(read)
# per = json.load(f2)
print(per)
两个模块的区别
反正推荐使用pickle模块
- json模块:
- 将对象转换成为字符串,不管是在哪种操作系统,哪种编程语言里,字符串都是可识别的。
- json就是用来在不同平台间传递数据的。
- 并不是所有的对象都可以直接转换成为一个字符串,下标列出了Python对象与json字符串的对应关系。
- 如果是一个自定义对象,默认无法装换成为json字符串,需要手动指定JSONEncoder.解码的时候就需要使用到JSONdecoder
- 如果是将一个json串重新转换成为对象,这个对象里的方法就无法使用了。
import json
class MyEncode(json.JSONEncoder):
def default(self, o):
# return {"name":o.name,"age":o.age}
return o.__dict__
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name+'正在吃东西')
p1 = Person('zhangsan', 18)
# 自定义对象想要转换成为json字符串,需要给这个自定义对象指定JSONEncoder
result = json.dumps(p1, cls=MyEncode)
print(result) # {"name": "zhangsan", "age": 18}
# 调用loads方法将对象加载成为一个对象以后,得到的结果是一个字典
p = json.loads(result)
print(type(p))
pickle模块:
- pickle序列化是将对象按照一定的规则转换成为二进制保存,它不能跨平台传递数据。
- pickle的序列化会将对象的所有数据都保存。