14文件的操作,指针定位,csv文件,序列化和反序列化

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的序列化会将对象的所有数据都保存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值