day 16 基础文件处理与字符串编码

字符--------(翻译过程)------->数字
  这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码
- 内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快)
- 硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。
无论是何种编辑器,要防止文件出现乱码(请一定注意,存放一段代码的文件也仅仅只是一个普通文件而已,此处指的是文件没有执行前,我们打开文件时出现的乱码)
核心法则就是,文件以什么编码保存的,就以什么编码方式打开
程序的执行
 
python test.py (我再强调一遍,执行test.py的第一步,一定是先将文件内容读入到内存中)
 
阶段一:启动python解释器
阶段二:python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中
此时,python解释器会读取test.py的第一行内容,#coding:utf-8,来决定以什么编码格式来读入内存,这一行就是来设定python解释器这个软件的编码使用的编码格式这个编码,
可以用sys.getdefaultencoding()查看,如果不在python文件指定头信息#-*-coding:utf-8-*-,那就使用默认的
python2中默认使用ascii,python3中默认使用utf-8
阶段三:读取已经加载到内存的代码(unicode编码的二进制),然后执行,执行过程中可能会开辟新的内存空间,比如x="egon"
内存的编码使用unicode,不代表内存中全都是unicode编码的二进制,
 
在程序执行之前,内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的
 
但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,比如x="egon",会被python解释器识别为字符串,会申请内存空间来存放"hello",然后让x指向该内存地址,此时新申请的该内存地址保存也是unicode编码的egon,如果代码换成x="egon".encode('utf-8'),那么新申请的内存空间里存放的就是utf-8编码的字符串egon了
python2与python3的区别
 
回到顶部
 
5.3.1 在python2中有两种字符串类型str和unicode
str类型
当python解释器执行到产生字符串的代码时(例如s='林'),会申请新的内存地址,然后将'林'encode成文件开头指定的编码格式,这已经是encode之后的结果了,所以s只能decode
 
1 #_*_coding:gbk_*_
2 #!/usr/bin/env python
4 x='林'5 # print x.encode('gbk') #报错
6 print x.decode('gbk') #结果:林
 
所以很重要的一点是:
 
在python2中,str就是编码后的结果bytes,str=bytes,所以在python2中,unicode字符编码的结果是str/bytes
 
 
#coding:utf-8
s='林' #在执行时,'林'会被以conding:utf-8的形式保存到新的内存空间中
 
print repr(s) #'\xe6\x9e\x97' 三个Bytes,证明确实是utf-8print type(s) #<type 'str'>
s.decode('utf-8')
# s.encode('utf-8') #报错,s为编码后的结果bytes,所以只能decode
 
unicode类型
当python解释器执行到产生字符串的代码时(例如s=u'林'),会申请新的内存地址,然后将'林'以unicode的格式存放到新的内存空间中,所以s只能encode,不能decode
 
s=u'林'print repr(s) #u'\u6797'print type(s) #<type 'unicode'>
# s.decode('utf-8') #报错,s为unicode,所以只能encode
s.encode('utf-8')
 
打印到终端
对于print需要特别说明的是:
 
当程序执行时,比如
 
x='林'
 
print(x) #这一步是将x指向的那块新的内存空间(非代码所在的内存空间)中的内存,打印到终端,而终端仍然是运行于内存中的,所以这打印可以理解为从内存打印到内存,即内存->内存,unicode->unicode
 
 
对于unicode格式的数据来说,无论怎么打印,都不会乱码
python3中的字符串与python2中的u'字符串',都是unicode,所以无论如何打印都不会乱码
 
基本操作
2.1 文件操作基本流程初探
 
f = open('chenli.txt') #打开文件
first_line = f.readline()
print('first line:',first_line) #读一行print('我是分隔线'.center(50,'-'))
data = f.read()# 读取剩下的所有内容,文件大时不要用print(data) #打印读取内容 
f.close() #关闭文件
文件打开模式
 
1 文件句柄 = open('文件路径', '模式')
 
打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。
打开文件的模式有:
 
- r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
- w,只写模式【不可读;不存在则创建;存在则清空内容】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【可读; 不存在则创建;存在则只追加内容】
 
"+" 表示可以同时读写某个文件
 
- r+, 读写【可读,可写】
- w+,写读【可读,可写】
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】
 
 "b"表示以字节的方式操作
 
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
 
 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
 
回到顶部
 
2.4 文件内置函数flush
 
flush原理:
 
- 文件操作是通过软件将文件从硬盘读到内存
- 写入文件的操作也都是存入内存缓冲区buffer(内存速度快于硬盘,如果写入文件的数据都从内存刷到硬盘,内存与硬盘的速度延迟会被无限放大,效率变低,所以要刷到硬盘的数据我们统一往内存的一小块空间即buffer中放,一段时间后操作系统会将buffer中数据一次性刷到硬盘)
- flush即,强制将写入的数据刷到硬盘
文件内光标移动
 
注意:read(3)代表读取3个字符,其余的文件内光标移动都是以字节为单位如seek,tell,read,truncate
 
posted @ 2017-06-19 15:55  lazy宇  阅读(107)  评论(0编辑  收藏  举报