Python基础(5)_字符编码、文件处理

一、文件读取过程:

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

  打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失,因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。

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

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

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

  第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中

  第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码 

总结:

  1. python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样
  2. 与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容

二、字符编码

1、字符编码的作用:程序员用字符编程,而计算机只能识别二进制0、1,因此字符编码的作用是将人操作的字符,翻译成计算机能识别的二进制数字

即、

  字符--------(翻译过程)------->数字 

  这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

2、字符编码的发展史

阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII

  ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符

阶段二:为了满足中文,中国人定制了GBK

 

  GBK: 2Bytes代表一个字符

 

  为了满足其他国家,各个国家纷纷定制了自己的编码

 

  日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr

 

阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。于是产生了unicode

  Unicode:统一用2Bytes代表一个字符,2**16-1=65535,可代表6万多个字符,因而兼容万国语言,其缺点是:对于通篇都是英文的文本来说,占内存较大

  UTF-8:解决占内存较大的问题,对英文字符只用1Bytes表示,对中文字符用3Bytes

总结:

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

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

Unicode和utf-8应用:

  1、内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快)

  2、硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。

3、字符编码的使用

从内存往硬盘存文件:encode

内存从硬盘读取文件:decode

 

文件乱码情况分析:

  乱码一:存文件时就已经乱码。例如中文汉字以日文编码shiftjis去存,此乱码无法恢复

  乱码二:存文件时不乱码而读文件时乱码。存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,此乱码可恢复,选对正确的解码方式就ok了

总结:

  无论是何种编辑器,要防止文件出现乱码(请一定注意,存放一段代码的文件也仅仅只是一个普通文件而已,此处指的是文件没有执行前,我们打开文件时出现的乱码)核心法则就是,文件以什么编码保存的,就以什么编码方式打开

 4、程序的执行

 

阶段一:启动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了

5、在python3中有两种字符串类型str和bytes

str是unicode

1 #coding:utf-8
2 s='' #当程序执行时,无需加u,''也会被以unicode形式保存新的内存空间中,
3 
4 #s可以直接encode成任意编码格式
5 s.encode('utf-8')
6 s.encode('gbk')
7 
8 print(type(s)) #<class 'str'>

bytes是bytes

 1 #coding:utf-8
 2 s='' #当程序执行时,无需加u,''也会被以unicode形式保存新的内存空间中,
 3 
 4 #s可以直接encode成任意编码格式
 5 s1=s.encode('utf-8')
 6 s2=s.encode('gbk')
 7 
 8 
 9 
10 print(s) #林
11 print(s1) #b'\xe6\x9e\x97' 在python3中,是什么就打印什么
12 print(s2) #b'\xc1\xd6' 同上
13 
14 print(type(s)) #<class 'str'>
15 print(type(s1)) #<class 'bytes'>
16 print(type(s2)) #<class 'bytes'>

 

三、文件处理

1、文件操作的基本流程:

1 f = open('chenli.txt') #打开文件
2 first_line = f.readline()
3 print('first line:',first_line) #读一行
4 print('我是分隔线'.center(50,'-'))
5 data = f.read()# 读取剩下的所有内容,文件大时不要用
6 print(data) #打印读取内容
7  
8 f.close() #关闭文件

2、文件打开模式

文件句柄 = open('文件路径', '模式')

打开文件的模式有:

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

  注:python中文件绝对路径写法:

    f=open('D:\\python\\a.txt')

  或者:

    f=open(r'D:\python\a.txt')

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

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

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

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

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

3、文件处理:控制指针到指定位置

  read(3)代表读取3个字符,其余的文件内光标移动都是以字节为单位如seek,tell,read,truncate

  seek 查找光标,每次默认从开始找

  f.seek(3,0)

  f.seek(3,1)当前位置

  f.seek(3,2)末尾

4、上下文管理

为了避免打开文件后忘记关闭,可以通过管理上下文

即:

with open('log','r',encoding='utf-8') as f:

如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。

上下文管理应用实例:

修改a.txt文件内容

 1 #上下文管理with
 2 # read_f=open('a.txt','r',encoding='utf-8')
 3 # write_f=open('.a.txt.swp','w',encoding='utf-8')
 4 import os
 5 with open('a.txt','r',encoding='utf-8') as read_f,\
 6         open('.a.txt.swp','w',encoding='utf-8') as write_f:
 7     for line in read_f:
 8         if 'alex' in line:
 9             line=line.replace('alex','ALEXSB')
10         write_f.write(line)
11 os.remove('a.txt')
12 os.rename('.a.txt.swp','a.txt')

 5、循环读取文件的方法 

索引循环文件读取方法:先全部读取,存入内存,此方法占内存

循环文件读取方法:占用内存少

 

python中变量名全部大写当作常量

OLDBOY_AGE=57

 

posted @ 2017-06-10 19:03  hedeyong11  阅读(298)  评论(1编辑  收藏  举报