文件操作、编码解码

模块:流(分为 输入流 和 输出流 两大类):I(input)/O(output)
流 用于读写文件,咱们所写的文件一般都是存在硬盘里的(C盘、D盘…),然后想把硬盘里的文件内容读出来,这个时候我们就使用流技术

一. 编码

正常咱们发微信、短信等,传文本,对方能够一目了然收到信息的叫明文,明文只要你认识字,一看就能看明白的
反过来,暗文就是直接不容易看懂的,比如从事地下工作的传递信息,需要翻译成明文才能获取信息

从明文转暗文的过程叫编码,从暗文转明文的过程叫解码
    
      编码
明  --------> 暗
文  <-------- 文
      解码

计算机在存储的时候只认识 0和1,0101的就相当于暗文,想让计算机帮忙存信息,最后都会转换成0101的形式,但每次我们打开文件查看的时候能显示出来的明文,只是计算机底层存信息是0101的暗文形式,所以查看文件和存储文件的时候计算机就有一个编码和解码的过程

ASCII(0-127)                                8
ANSI(拉丁文)                                 8
GB2312(7000)        要求前八位和后八位都得大于127时才表示汉字    16
                     小于127时表示的是其他东西不是汉字           
GBK(gb2312,2万多)    只要求前八位>127                  16
UNICODE                                    16
UTF-8(推荐)                               8 or 24

在这里插入图片描述
这个Python打印出来的是解码之后的字符串 —> asdfgk

Python2中, 
string  (str,unicode)  
str类型+unicode类型,相加的话  str类型会自动转成unicode运行没有问题

Python3中, 
string (str,bytes)    
str类型+bytes类型,相加的话   这种情况会报错,不同类型不能相加

注:unicode类型 是前面加 u, bytes类型 是前面加 b
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

json.dumps()就是一个小工具,利用它把内存里的原型显示出来

json 是一个规则,不同的语言之间进行交换,是采用json这种格式来进行交换,因为这种格式规则已经定好了,大家都一致认可,所以交换的时候,传递的数据格式就是一种json格式
在这里插入图片描述
单纯就写一个字符串,默认是unicode编码,你给它encode编码就类型不一样了,一个短一个长,encode编码指bytes类型,unicode编码指string类型
在这里插入图片描述
encode编码,decode解码
在这里插入图片描述
编码规则和解码规则不一致时就会出现乱码

写爬虫的时候最容易出现乱码,爬取对象是一种编码方式,爬虫解码时是另一种方式;所以编码方式和解码方式必须统一,才不会出现乱码

打开文件,读取文件内容:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

f = open("0920.txt",encoding="utf8")      
#读文件打开(open)的时候就已经开始解码了,
#不是在下面打印输出读取文件内容时解码!    
print(f.read())

在这里插入图片描述

读的时候就不能按unicode的方式读,因为存文本的时候是按utf-8存的,所以解码的时候就要按utf-8的方式解码
中文字符,一个字符占三个字节

二. I/O操作

从硬盘读的数据,读到代码里(代码都是存在硬盘里的),叫输入流
从代码里,把数据写到文件里,叫输出流

I-input   输入       读取数据
O-output  输出       写入数据

新建一个utf-8.txt文本:
在这里插入图片描述
流对象
在这里插入图片描述

open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True)

在这里插入图片描述

r     -    只读      str
rb    -     读      bytes
r+    -   用于读写   指针在开头
flush --  清空缓存

在这里插入图片描述
看,结果。。。
在这里插入图片描述
在这里插入图片描述
打开文件
在这里插入图片描述

fio = open("utf-8.txt",mode="r",encoding="utf8")
list = fio.readlines()
for index,line in enumerate(list):
    if index==9:
        print("-----------分割线----------")
        continue
    print(line.strip())

第10行开始,就划线没有了
在这里插入图片描述

#fio.write("I will go home!")
#io.write('\nByeBye!')
#fio.write('\nadfas')
#data = fio.readline()
#while data != "":
#print(data)
#data = fio.readline()

#fio = open("utf-8.txt",mode="r",encoding="utf8")
#print(fio.read())
#fio.write("I will go home!")
#io.write('\nByeBye!')
#fio.write('\nadfas')
#data = fio.readline()
#while data != "":
#print(data)
#data = fio.readline()

‘’’

fio = open("utf-8.txt",mode="r",encoding="utf8")
print(fio.tell())  

‘’’
打印光标所在位置:
在这里插入图片描述
‘’’

fio = open("utf-8.txt",mode="r",encoding="utf8")
for line in fio:
print(line.strip())
'''

'''
print(fio.readline())
print(fio.readline())
print(fio.readline())
fio.seek(0)
print(fio.readline())
print(fio.tell())
'''

'''
# 打印进度条
import sys,time    #导入 
for i in range(101):
   sys.stdout.write("#")
   sys.stdout.flush()
   time.sleep(0.3)     #休眠一下,0.3秒

''’

在这里插入图片描述

f = open("utf-8.txt",encoding="utf-8")
try:
  print(f.read())
  print(1 / 0)
except:
  pass
finally:
  f.close()

:用try的方式代码有点冗长,下面了解with使用后,就能有更好的选择
在这里插入图片描述

import sys
print(sys.getdefaultencoding())

在这里插入图片描述

三. with

使用with打开文件
with用于释放资源用的
with资源释放
with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭线程中锁的自动获取和释放等。

'''
with open("utf-8.txt",encoding="utf-8") as f:
print(f.read())
print(1 / 0)
'''

在这里插入图片描述
with工作原理
(1)紧跟with后面的语句被求值后,返回对象的“-enter+()”方法被调用,这个方法的返回值将被赋给as后面的变量
(2)当with后面的代码块全部被执行完之后,将调用前面返回对象的“-exit-()”方法

class demo(object):

   def __enter__(self):
      print("进入enter方法")
      return self
   def __exit__(self, exc_type, exc_val, exc_tb):
      print("进入exit方法")
      print("---",exc_type)
      print("---",exc_val)
      print("---",exc_tb)

在这里插入图片描述

四. 文件和路径的常用操作

上述是对文件内容进行操作,本部分对文件整体进行操作

1.open函数

当使用python的内置函数open()打开一个文件后,就会返回一个文件对象,open()常用的格式如下:

f = open(filename. mode)

fileinput :好处

文件合并和拆分
文件复制
文件加密

‘’’
‘’’
#不安全代码
f = open(“a.txt”,encoding=“utf-8”)
print(f.read())
print(1/0)
f.close()
‘’’
‘’’

‘’’
import fileinput
with fileinput.input([“a.mp4”,“b.mp4”],mode=“rb”) as lines,open(“c.mp4”,mode=“wb”) as f:
for line in lines:
f.write(line)
‘’’
‘’’
import fileinput
f = fileinput.input(“a.txt”,mode=“rb”)
for line in f:
print(line.decode(“utf-8”))
‘’’
import os
#print(os.getcwd())#获取当前目录
#print(os.listdir(“F:\教学视频\python”))#获取文件目录下所有文件和文件夹
#os.mkdir(“new”)
#os.rmdir(“new”)
#print(os.path.isdir(“new”))
#print(os.path.isfile(“a.html”))
‘’’
for i in os.walk("./"):
print(i)
‘’’
‘’’
def bf(path):
list = os.listdir(path)
for item in list:
if os.path.isfile(os.path.join(path,item)):#path+"/"+item
print(item)
else:
print(item)
bf(os.path.join(path,item))

bf(“C:/Users/aqiu/PycharmProjects/test1901_01”)
‘’’
‘’’
1、pickle模块
2、json模块
3、json与pickle模块的区别
4、shelve模块

1、pickle模块
python持久化的存储数据:

python程序运行中得到了一些字符串,列表,字典等数据,想要长久的保存下来,方便以后使用,
而不是简单的放入内存中关机断电就丢失数据。python模块大全中pickle模块就排上用场了,
他可以将对象转换为一种可以传输或存储的格式。

pickle模块将任意一个python对象转换成一系统字节的这个操作过程叫做串行化对象。

python的pickle模块实现了python的所有数据序列和反序列化。基本上功能使用和JSON模块没有太大区别,方法也同样是dumps/dump和loads/load。cPickle是pickle模块的C语言编译版本相对速度更快。

与JSON不同的是pickle不是用于多种语言间的数据传输,它仅作为python对象的持久化或者python程序间进行互相传输对象的方法,因此它支持了python所有的数据类型。

import pickle

data2 = [1,2,3,4]
det_str = pickle.dumps(data2)
print(det_str)

#output: 输出为二进制格式
b’\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.’

#将数据序列化后存储到文件中
f = open(‘test.txt’,‘wb’) #pickle只能以二进制格式存储数据到文件
data = {‘k1’:‘python’,‘k2’:‘java’}
f.write(pickle.dumps(data)) #dumps序列化源数据后写入文件
f.close()

#反序列化读取源数据
import pickle
f = open(‘test.txt’,‘rb’)
da = pickle.loads(f.read()) #使用loads反序列化
print(da)

dumps和dump,load和loads的区别:

dumps是将对象序列化

dump是将对象序列化并保存到文件中

loads将序列化字符串反序列化

load将序列化字符串从文件读取并反序列化

import pickle

data1 = [1,‘a’,2,‘b’,3,‘c’]
pi = pickle.dumps(data1) #序列化对象
print(pi)
print(pickle.loads(pi)) #反序列化对象

f = open(‘test1.txt’,‘wb’)
data2 = [‘py’,‘th’,‘on’,123]
pickle.dump(data2,f) #序列化对象到文件
f = open(‘test1.txt’,‘rb’)
red = pickle.load(f) #从文件中反序列化对象
print(red)

2、json模块
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯
(包括C、C++、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。
易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。

json.dump(obj,fp,*,skipkeys = False,ensure_ascii = True,check_circular = True,
indent = None,separators = None,default = None,sort_keys = False,** kw)

将obj对象格式化并存储到文件对象中,文件必须为可写的文件句柄,json只产生str对象,
不支持bytes对象,所以fp.write()必须支持str输入

skipkeys如果为True,对象的基本类型必须是str,int,float,bool,None

ensure_ascii=True,如果为true则所以传入的非ASCII字符都被转义,如果为false则字符将原样输出

check_circular=True,如果为true容器类型的循环引用检查将被跳过

indent=None,表示数组元素和对象将按指定的值缩进,可以是整数或字符串如’\t’

sort_keys=False,如果为True字典的输出将按键排序

import json

data=[{‘k1’:‘v1’,‘k2’:‘v2’},{‘k3’:‘v3’,‘k4’:‘k4’},{‘k6’:‘v6’,‘k5’:‘k5’}]

with open(‘test.txt’,‘w’) as pf:
json.dump(data,pf,indent=2,sort_keys=True)
pf.close()

#output
[
{
“k1”: “v1”,
“k2”: “v2”
},
{
“k3”: “v3”,
“k4”: “k4”
},
{
“k5”: “k5”,
“k6”: “v6”
}
]

json.dumps(obj,*,skipkeys = False,ensure_ascii = True,check_circular = True,indent = None,separators = None,default = None,sort_keys = False,** kw)

将obj对象格式化为str对象,参数含义和dump相同

import json
data=[{‘k1’:‘v1’,‘k2’:‘v2’},{‘k3’:‘v3’,‘k4’:‘k4’},{‘k6’:‘v6’,‘k5’:‘k5’}]

pi = json.dumps(data,indent=2,sort_keys=True)
print(type(pi))
print(pi)
p2=json.loads(pi)
print(type(p2))
print(p2)

<class ‘str’>
[
{
“k1”: “v1”,
“k2”: “v2”
},
{
“k3”: “v3”,
“k4”: “k4”
},
{
“k5”: “k5”,
“k6”: “v6”
}
]
<class ‘list’>
[{‘k1’: ‘v1’, ‘k2’: ‘v2’}, {‘k3’: ‘v3’, ‘k4’: ‘k4’}, {‘k5’: ‘k5’, ‘k6’: ‘v6’}]

json.load(fp,*,cls=None,object_hook=None,parse_float=None,parse_int=None,parse_constant=None,object_pairs_hook=None,**kw)

将文件对象反序列化为python对象,选项参数用来指定类型解码,在python3.6中fp可以使用二进制文件

import json

with open(‘test.txt’,‘rb’) as fp:
data1=json.load(fp)
print(type(data1))
print(data1)

<class ‘list’>
[{‘k1’: ‘v1’, ‘k2’: ‘v2’}, {‘k3’: ‘v3’, ‘k4’: ‘k4’}, {‘k5’: ‘k5’, ‘k6’: ‘v6’}]

json.loads(s,*,encoding=None,cls=None,object_hook=None,parse_float=None,parse_int=None,parse_constant=None,object_pairs_hook=None,**kw)

将json文档的实例反序列化为python对象,参数含义同load()相同

import json
with open(‘test.txt’,‘rb’) as fp:
data1=json.loads(fp.read())
print(type(data1))
print(data1)

3、json与pickle模块的区别
1、JSON只能处理基本数据类型。pickle能处理所有Python的数据类型。

2、JSON用于各种语言之间的字符转换。pickle用于Python程序对象的持久化或者Python程序间对象网络传输,但不同版本的Python序列化可能还有差异。

4、shelve模块
shelve与pickle类似用来持久化数据的,不过shelve是以键值对的形式,将内存中的数据通过文件持久化,
值支持任何pickle支持的python数据格式,它会在目录下生成三个文件。

import shelve

import tab
s = shelve.open(‘test_s.db’) #创建shelve并打开
s[‘k1’]={‘int’:10,‘float’:8.8,‘string’:‘python’} #写入数据
s.close() #关闭文件
s = shelve.open(‘test_s.db’) #打开文件
print(s[‘k1’]) #访问shelve中的数据
{‘float’: 8.8, ‘string’: ‘python’, ‘int’: 10}

print(s[‘k1’][‘int’])
10

s.close()

对于存储的key,value值,只能添加key,value,可修改整个value,不能单独修改列表或字典中的元素

s = shelve.open(‘test_s.db’,flag=‘r’)

print(s[‘k1’])
{‘float’: 8.8, ‘string’: ‘python’, ‘int’: 10}

s[‘k2’]=[1,2,3] #添加数据
print(s[‘k2’])
[1, 2, 3]

s[‘k2’][0]=99 #修改存储的value的单个值时不生效也不报错
print(s[‘k2’])
[1, 2, 3]

s.close()

s = shelve.open(‘test_s.db’,flag=‘c’)
s.keys()
KeysView(<shelve.DbfilenameShelf object at 0x7fd4770f1850>)

len(s)
2

s[‘k2’]=(33,44) #可以修改key的value
print(s)
<shelve.DbfilenameShelf object at 0x7fd4770f1850>

print(s[‘k2’])
(33, 44)

写回(write-back)由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。

上面这个例子中,由于一开始我们使用了缺省参数shelve.open()了,因此修改的值即使我们s.close()也不会被保存。

所以当我们试图让shelve去自动捕获对象的变化,我们应该在打开shelf的时候将writeback设置为True。当我们将writeback这个flag设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。当我们close()打开的shelf的时候,缓存中所有的对象会被重新写入DB。

s = shelve.open(‘test_s.db’,writeback=True) #使用回写功能打开
print(s[‘k1’]) #初始值
{‘float’: 8.8, ‘string’: ‘python’, ‘int’: 10}

print(s[‘k2’])
(33, 44)

s[‘k1’][‘float’]=‘99.99’ #修改字典中的元素
print(s[‘k1’]) #成功修改
{‘float’: ‘99.99’, ‘string’: ‘python’, ‘int’: 10}

writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。

print(s[‘k1’])
{‘float’: ‘99.99’, ‘string’: ‘python’, ‘int’: 10}

s[‘k1’][‘list’]=[1,2,3]
s[‘k1’][‘tuple’]=(4,5,6)
s[‘k1’][‘dic’]={‘a’:123,‘b’:456}
print(s[‘k1’])
{‘dic’: {‘b’: 456, ‘a’: 123}, ‘int’: 10, ‘float’: ‘99.99’, ‘string’: ‘python’, ‘tuple’: (4, 5, 6), ‘list’: [1, 2, 3]}
‘’’
import pickle
#将数据序列化后存储到文件中
f = open(‘test.txt’,‘wb’) #pickle只能以二进制格式存储数据到文件
data = {‘k1’:‘python’,‘k2’:‘java’}
f.write(pickle.dumps(data)) #dumps序列化源数据后写入文件
f.close()

#反序列化读取源数据
import pickle
f = open(‘test.txt’,‘rb’)
da = pickle.loads(f.read()) #使用loads反序列化
print(da)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值