day 10 字符编码和文件处理 细节整理

时间:2022-02-25 21:07:55

pycharm是文本编辑器。

大概理解为:  输出到屏幕上的时候,是解码过的字符串,用 decode

       处理的时候要编码成相应的流, encode 成你要用的格式就可以了

1 .字符编码:

  字符====== (翻译过程)=======》数字。

utf-8是unicode的变种,是万国编码。

 2. 文本编辑器存取文件的原理(nodepad++,pycharm,word)

    打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失

因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。

在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

 3python解释器执行py文件的原理 ,例如python test.py

    第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器

    第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中(小复习:pyhon的解释性,决定了解释器只关心文件内容,不关心文件后缀名)

    第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码( ps:在该阶段,即执行时,才会识别python的语法,执行文件内代码,执行到name="ff",会开辟内存空间存放字符串"ff")

  

  总结:python解释器于文件本编辑的异同

     相同点:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样

不同点:文本编辑器将文件内容读入内存后,是为了显示/编辑,而python解释器将文件内容读入内存后,是为了执行(识别python语法)

 

  1. 一个python文件中的内容是由一堆字符组成的(python文件未执行时)

  2. python中的数据类型字符串是由一串字符组成的(python文件执行时)

day 10 字符编码和文件处理   细节整理

强调!!!

  强调!!!!

  强调!!!

unicode:简单粗暴,所有字符都是2Bytes,优点是字符->数字的转换速度快,缺点是占用空间大

utf-8:精准,对不同的字符用不同的长度表示,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表示

   哪些场景涉及字符编码? 

  1. 内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快)
  2. 硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。

       什么是乱码

文件从内存刷到硬盘的操作简称存文件

文件从硬盘读到内存的操作简称读文件

乱码一:存文件时就已经乱码

存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,

本质上其他国家的文字由于在shiftjis中没有找到对应关系而导致存储失败,用open函数的write可以测试,f=open('a.txt','w',encodig='shift_jis')

f.write('你瞅啥\n何を見て\n') #'你瞅啥'因为在shiftjis中没有找到对应关系而无法保存成功,只存'何を見て\n'可以成功

但当我们用文件编辑器去存的时候,编辑器会帮我们做转换,保证中文也能用shiftjis存储(硬存,必然乱码),这就导致了,存文件阶段就已经发生乱码

此时当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了

再或者,存文件时:

f=open('a.txt','wb')

f.write('何を見て\n'.encode('shift_jis'))
f.write('你愁啥\n'.encode('gbk'))
f.write('你看啥\n'.encode('utf-8'))
f.close()

以任何编码打开文件a.txt都会出现其余两个无法正常显示的问题

乱码二:存文件时不乱码而读文件时乱码

存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了,而存文件时乱码,则是一种数据的损坏。

###程序的执行!!!

python test.py   (我再强调一遍,执行test.py的第一步,一定是先将文件内容读入到内存中)

阶段一:  启动python解释器

阶段二:  python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中

阶段三:  读取已经加载到内存的代码(unicode编码的二进制),然后执行,执行过程中可能会开辟新的内存空间,比如x="ff"

打印到终端

对于print需要特别说明的是:

当程序执行时,比如

x='fly'

print(x) #这一步是将x指向的那块新的内存空间(非代码所在的内存空间)中的内存,打印到终端,而终端仍然是运行于内存中的,所以这打印可以理解为从内存打印到内存,即内存->内存,unicode->unicode

对于unicode格式的数据来说,无论怎么打印,都不会乱码

python3中的字符串与python2中的'字符串',都是unicode,所以无论如何打印都不会乱码

字符编码就到这差不多就要结束了, 下面我代表组织给大家传达一下组织近期的精神。 我希望大家用心听,用心学,时间是宝贵的,我们要在最短的时间内,尽可能的学到更多更好更棒棒的东西哟!   每天进步一点点,一个星期就是一大步,不要和别人比,因为你需要战胜的只由你自己。加油 ,  我们都是最棒的 !!!

总结!!!!

1 以什么编码存的就要以什么编码取出
ps:内存固定使用unicode编码,
我们可以控制的编码是往硬盘存放或者基于网络传输选择编码

2 数据是最先产生于内存中,是unicode格式,要想传输需要转成bytes格式
#unicode----->encode(utf-8)------>bytes
拿到bytes,就可以往文件内存放或者基于网络传输
#bytes------>decode(gbk)------->unicode

3 python3中字符串被识别成unicode
python3中的字符串encode得到bytes

4 了解
python2中的字符串就bytes
python2中在字符串前加u,就是unicode

以上就是字符编码的基础知识

 下面我们就进入文件处理

一:文件操作的基本流程:

f = open('i.txt') #打开文件
first_line = f.readline()
print('first line:',first_line) #读一行
print('我是分隔线'.center(50,'-'))
data = f.read()# 读取剩下的所有内容,文件大时不要用
print(data) #打印读取内容

f.close() #关闭文件

#不指定打开编码,默认使用操作系统的编码,windows为gbk,linux为utf-8,与解释器编码无关
f=open('chenli.txt',encoding='gbk') #在windows中默认使用的也是gbk编码,此时不指定编码也行
f.read()


二: 文件的打开方式
文件句柄 = open('文件路径', '模式')   #f=open('1.py,encoding='utf-8')

打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。

打开文件的模式有:

  • r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
  • w,只写模式【不可读;不存在则创建;存在则清空内容】
  • x, 只写模式【不可读;不存在则创建,存在则报错】
  • a, 追加模式【可读;   不存在则创建;存在则只追加内容】

"+" 表示可以同时读写某个文件

  • r+, 读写【可读,可写】
  • w+,写读【可读,可写】
  • x+ ,写读【可读,可写】
  • a+, 写读【可读,可写】

"b"表示以字节的方式操作

  • rb  或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

# f=open(r'aaaa.py',encoding='utf-8') #x=1
# # print('+++++>1',f.read())
# # print(type(data))
# # print('+++++>2',f.read())
# # print('+++++>3',f.read())
# f.close()
# print(f)
# f.read()
# # del f

#open:

1: 会面向操作系统发起一个系统调用,操作会打开一个文件。

2:在python中会产生一个值 指向操作系统打开的那个文件,我们可以把该值赋给一个变量

#回收资源:

1:f.close()一定要做,关闭操作系统打开的文件,即回收操作系统的资源

2:del f: 没必要做,因为在python程序运行完毕后,会自动清理与该程序有关的所有内存空间。

#只读模式, 文件不存在报错

f = open('res.py',encoding='utf-8')

print(f.read())

print(f.readline(),end='')

print(f.readlines())

print(f.readable())

print(f.writable())  #False

f.close()

#文本文件:只写模式,文件不存在则创建空文件,文件存在则清空
# f=open('new.txt','w',encoding='utf-8')
# f.write('1111111\n')
# f.writelines(['22222\n','3333\n','444444\n'])
# # print(f.writable())
# f.close()

#文本文件:只追加写模式,文件不存在则创建,文件存在
# f=open('new_2','a',encoding='utf-8')
# print(f.readable())
# print(f.writable())

# f.write('33333\n')
# f.write('44444\n')
# f.writelines(['5555\n','6666\n'])

# f.close()

#rb
# f=open('aaaa.py','rb')
# print(f.read().decode('utf-8'))

# f=open('1.jpg','rb')
# data=f.read()

#wb
# f=open('2.jpg','wb')
# f.write(data)
# f=open('new_3.txt','wb')
# f.write('aaaaa\n'.encode('utf-8'))

#ab
f=open('new_3.txt','ab')
f.write('aaaaa\n'.encode('utf-8'))
#上下文管理
# with open('aaaa.py','r',encoding='utf-8') as read_f,\
# open('aaaa_new.py','w',encoding='utf-8') as write_f:
# data=read_f.read()
# write_f.write(data)

#循环取文件每一行内容
# with open('a.txt','r',encoding='utf-8') as f:
# while True:
# line=f.readline()
# if not line:break
# print(line,end='')

# lines=f.readlines() #只适用于小文件
# print(lines)

# data=f.read()
# print(type(data))

# for line in f: #推荐使用
# print(line,end='')

#文件的修改
#方式一:只适用于小文件
# import os
# with open('a.txt','r',encoding='utf-8') as read_f,\
# open('a.txt.swap','w',encoding='utf-8') as write_f:
# data=read_f.read()
# write_f.write(data.replace('alex_SB','alex_BSB'))
#
# os.remove('a.txt')
# os.rename('a.txt.swap','a.txt')

#方式二:
import os
with open('a.txt','r',encoding='utf-8') as read_f,\
open('a.txt.swap','w',encoding='utf-8') as write_f:
for line in read_f:
write_f.write(line.replace('alex_BSB','BB_alex_SB'))

os.remove('a.txt')
os.rename('a.txt.swap','a.txt')