20,190,808 character encoding, file operations

Character Encoding

First, basic computer

  1. cpu: controlling the operation of the program (text editor removed from the memory data is read into memory)
  2. Memory: (cpu data after the operation, the memory contains a text editor) to run the program
  3. Hard: storing data (text editor)


046- character encoding -? Basic Computer .png x-oss-process = style / watermark

Second, text editor, file access principle

Computer known only 0 and 1

The role of the text editor: read and write data, save data

  1. Open the editor will open to start a process, it is in memory, so content with the editor to write and are also stored in memory, data loss after power failure.

  2. To permanently preserved, you need to click the Save button: the brush editor memory data to the hard disk.

  3. We write a py file (not implemented), there is no difference with the preparation of other documents, I am just writing a bunch of characters only.

Three, Python interpreter to execute py file principle

Function has a text editor

010101011001010 -> a = 1 # 5 very ordinary character, is not running when the python interpreter provided # character encoding

Define the variable will open up the memory space to store variables, memory that is known only 0 and 1, a = 1 -> 01010110101 take some 0 and 1 # python2 he provided a string, when the python interpreter run and the difference between 3 character encoding

  • The first stage: Python interpreter starts, then start the equivalent of a text editor
  • The second stage: Python interpreter equivalent of a text editor to open test.py file, read from the content on the hard disk test.py file into memory (Small Review: pyhon interpretative decision concerned only the interpreter file contents, do not care about the file extension).
  • The third stage: Python interpreter interpreted just loaded into memory test.py code (ps: at this stage, that is when the real implementation of the code, will recognize the syntax, the code within the Python executable file, when executed to name = " egon ", the memory will open up space for the string" egon ").

Four, Python interpreter with files Editing of the similarities and differences

  • The same point: Python interpreter is interpreted contents of the file, so Python interpreter have read py file function, which is the same as with a text editor.
  • Different points: a text editor, file contents into memory, in order to display or edit, simply ignore Python syntax, but Python interpreter will file contents into memory, not in order to give you a peek in to write Python code the what, but to execute Python code that identifies the Python syntax.

Fifth, the character encoding introduction

5.1 What is a character encoding

The computer must be powered in order to work, ready to use 'power' computer-driven work that is characteristic of 'power' determines the characteristics of the computer. I.e., high and low electrical characteristics (human counterparts logically high level binary 1, binary 0 corresponding to a low level), on the magnetic properties of the disk is the same reason. Conclusion: The computer only recognize numbers.

Obviously, we usually use the computer, are used in human can read character (with the result of high-level language programming is also nothing more than writing a bunch of characters in the file), how to make computers understand human character?

We must go through a process:

  • -------- character "translation -------" Digital

In short, a character encoding human character encoding into a digital computer can recognize, this conversion must follow a fixed set of standards, which is nothing more than the correspondence between the digital human character, called the character code table.

5.2 relate to the character encoding of two scenes

  1. The contents of a file in Python is a bunch of characters, involve access to character encoding issues (Python file is not running, the first two stages belong to this category).
  2. Data type String are Python (Python when the file is executed, i.e. third stage) of a string of characters.

5.3 History of character encoding and classification

Computers were invented by the Americans, the first character encoding is ASCII, only the provisions of the correspondence between English alphanumeric and some special characters and numbers. 256 = 2 ** 8, therefore, the ASCII code symbols can represent up to 256: can only be represented (one byte), i.e., 8 bits.

046- character encoding -ASCII table .jpg? X-oss-process = style / watermark

Of course, we are programming languages ​​English no problem, ASCII enough, but when dealing with data, different countries have different languages, Chinese people will join the Chinese, the Japanese will join the Japanese in their program, but also Korean.

But to represent Chinese, take a single byte table shows a man, it is impossible to express finished (even a child will know more than two thousand Chinese characters), only one solution is to use a byte> 8 represents the binary , the more bits, the more representative of the change, so that you can get as much out of nowhere expression of Chinese characters.

所以中国人规定了自己的标准gb2312编码,规定了包含中文在内的字符与数字的对应关系。

日本人规定了自己的Shift_JIS编码;韩国人规定了自己的Euc-kr编码(另外,韩国人说,计算机是他们发明的,要求世界统一用韩国编码,但世界人民没有搭理他们)。

046- character encoding - summed up the history of the development of character encoding .png x-oss-process = style / watermark?

这时候问题出现了,精通18国语言的小周同学谦虚的用8国语言写了一篇文档,那么这篇文档,按照哪国的标准,都会出现乱码(因为此刻的各种标准都只是规定了自己国家的文字在内的字符跟数字的对应关系,如果单纯采用一种国家的编码格式,那么其余国家语言的文字在解析时就会出现乱码)。所以迫切需要一个世界的标准(能包含全世界的语言)于是Unicode应运而生(韩国人表示不服,然后没有什么卵用)。

ascii用1个字节(8位二进制)代表一个字符;Unicode常用2个字节(16位二进制)代表一个字符,生僻字需要用4个字节。

例:字母x,用ascii表示是十进制的120,二进制0111 1000。

汉字中已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。

字母x,用Unicode表示二进制0000 0000 0111 1000,所以Unicode兼容ascii,也兼容万国,是世界的标准。

这时候乱码问题消失了,所有的文档我们都使用但是新问题出现了,如果我们的文档通篇都是英文,你用Unicode会比ascii耗费多一倍的空间,在存储和传输上十分的低效。

本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的UTF-8(Unicode Transformation Format-8)编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

字符 ASCII Unicode UTF-8
A 01000001 00000000 01000001 01000001
x 01001110 00101101 11100100 10111000 10101101

从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

5.4 内存为什么不用UTF-8呢?

说了那么一大堆,那为什么内存用Unicode,而不直接使用UTF-8呢?这样不就可以直接把代码从内存直接丢入硬盘了吗?出现这个问题的原因是硬盘中还躺了其他国家的代码,各个国家的代码的二进制还需要运行在计算机上使用,因此内存中必须使用Unicode的编码,因为Unicode能和硬盘中其他国家的二进制中的代码进行转换,但是UTF-8只是简化了代码的存储,它并不能与其他国家硬盘中的代码进行关系转换。总而言之只有Unicode编码才能运行其他国家硬盘中的代码,而UTF-8的代码无法进行该操作。

内存中还使用Unicode编码,是因为历史遗留问题造成的,但是因为现在写代码使用的都是UTF-8代码,所以以后内存中的代码都将变成UTF-8代码,并且以前遗留的各个国家的代码都将被淘汰,所以未来内存中使用的编码也将使用UTF-8编码替代Unicode编码。

5.5 字符编码之文本编辑器操作

046- character encoding -? Text Editor 1.png x-oss-process = style / watermark

046- character encoding - text editor 2.png an x-oss-process = style / watermark?

046- character encoding - text editor 3.png an x-oss-process = style / watermark?

046- character encoding -? Text editor 4.png x-oss-process = style / watermark

5.6 乱码分析

首先明确概念

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

乱码的两种情况:

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

存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,
本质上其他国家的文字由于在shiftjis中没有找到对应关系而导致存储失败。但当我们硬要存的时候,编辑并不会报错(难道你的编码错误,编辑器这个软件就跟着崩溃了吗???),但毫无疑问,不能存而硬存,肯定是乱存了,即存文件阶段就已经发生乱码,而当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了。

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

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

六、总结

  1. 保证不乱码的核心法则就是,字符按照什么标准而编码的,就要按照什么标准解码,此处的标准指的就是字符编码。
  2. 在内存中写的所有字符,一视同仁,都是Unicode编码,比如我们打开编辑器,输入一个“你”,我们并不能说“你”就是一个汉字,此时它仅仅只是一个符号,该符号可能很多国家都在使用,根据我们使用的输入法不同这个字的样式可能也不太一样。只有在我们往硬盘保存或者基于网络传输时,才能确定”你“到底是一个汉字,还是一个日本字,这就是Unicode转换成其他编码格式的过程了。简而言之,就是内存中固定使用的就是Uncidoe编码,我们唯一能改变的就是存储到硬盘时使用的编码。
  • Unicode----->encode(编码)-------->gbk
  • Unicode<--------decode(解码)<----------gbk

046- and Unicode character encoding conversion -utf8 .png? X-oss-process = style / watermark

乱码的两种情况

中文的文本编辑器只认识中文,然后你输入了日文 --> 乱码 # encode 编码

文本编辑器存储了中文(文件),但是你用日本的编辑器打开这个文件 --> 乱码 # decode 解码

解决乱码

什么格式存储, 就什么格式读取 就不会乱码(牢记这句话)

windows电脑的记事本默认为gbk编码,除此之外其他的软件默认编码为utf8

python2和python3字符编码的区别

一、字符编码应用之python

1.1 执行python程序的三个阶段

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

test.py文件内容以gbk格式保存的,内容为:

The difference between 047-Python2 and 3 character encoding - .png write code x-oss-process = style / watermark?

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

此时,Python解释器会读取test.py的第一行内容,#coding:utf-8#-*-coding:utf-8-*-,以此决定以什么编码格式将代码读入内存,这一行就是设定Python解释器这个软件使用的编码格式。

可以用sys.getdefaultencoding()查看,如果不在Python文件指定头信息#-*-coding:utf-8-*-,那就使用Python默认的编码格式。

import sys

sys.getdefaultencoding()
'utf-8'

Python2中默认使用ascii,Python3中默认使用utf-8。

047-Python2 and 3 character encoding of difference -? Syntax error .png x-oss-process = style / watermark

改正:在test.py指定文件头,字符编码一定要为gbk。即更正为

#coding:gbk
你好啊

047-Python2 and 3 character encoding of difference -? Correction .png x-oss-process = style / watermark

  • 阶段三:读取已经加载到内存的代码(Unicode编码格式),然后执行,执行过程中可能会开辟新的内存空间,比如name="nick"

内存的编码使用Unicode,不代表内存中全都是Unicode,因为在程序执行之前,内存中确实都是Unicode,比如从文件中读取了一行name="nick",其中的name、等号、引号的地位都一样,都是普通字符而已,都是以Unicode的格式存放于内存中的。

但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间)用来存放Python的数据类型的值,而Python的字符串类型又涉及到了字符的概念。

比如name="nick",会被Python解释器识别为字符串,会申请内存空间来存放字符串类型的值,至于该字符串类型的值被识别成何种编码存放,这就与Python解释器的有关了,而Python2与Python3的字符串类型又有所不同。

二、Python2与Python3字符串类型的区别

2.1 Python2

在Python2中有两种字符串类型str和Unicode。

2.1.1 str类型

当Python解释器执行到产生字符串的代码时(例如x='上'),会申请新的内存地址,然后将'上'编码成文件开头指定的编码格式

因为直接print()会自动转换编码,我们使用encode()方法查看'上'的字符编码。

# 三、Python2中代码

# 四、coding:gbk

x = '上'
y = '下'
print([x, y])  # ['\xc9\xcf', '\xcf\xc2']
# 五、\x代表16进制,此处是c9cf总共4位16进制数,一个16进制四4个比特位,4个16进制数则是16个比特位,即2个Bytes,这就证明了按照gbk编码中文用2Bytes

print(type(x),type(y))  # (<type 'str'>, <type 'str'>)

理解字符编码的关键!!!

内存中的数据通常用16进制表示,2位16进制数据代表一个字节,如\xc9,代表两位16进制,一个字节

gbk存中文需要2个bytes,而存英文则需要1个bytes,它是如何做到的???!!!

gbk会在每个bytes,即8位bit的第一个位作为标志位,标志位为1则表示是中文字符,如果标志位为0则表示为英文字符。

x='你a好'`
转成gbk格式二进制位:`8bit+8bit+8bit+8bit+8bit=(1+7bit)+(1+7bit)+(0+7bit)+(1+7bit)+(1+7bit)

这样计算机按照从左往右的顺序读:

  1. 连续读到前两个括号内的首位标志位均为1,则构成一个中午字符:你
  2. 读到第三个括号的首位标志为0,则该8bit代表一个英文字符:a
  3. 连续读到后两个括号内的首位标志位均为1,则构成一个中午字符:好

也就是说,每个Bytes留给我们用来存真正值的有效位数只有7位,而在Unicode表中存放的只是这有效的7位,至于首位的标志位与具体的编码有关,即在Unicode中表示gbk的方式为:(7bit)+(7bit)+(7bit)+(7bit)+(7bit)

047-Python2与3字符编码的区别-gbk上.png?x-oss-process=style/watermark

按照上图翻译的结果,我们可以去Unicode关于汉字的对应关系中去查:链接:https://pan.baidu.com/s/1dEV3RYp

可以看到“上”对应的gbk(G0代表的是gbk)编码就为494F,即我们得出的结果,而上对应的Unicode编码为4E0A,我们可以将gbk-->decode-->Unicode。

047-Python2与3字符编码的区别-Unicode上.png?x-oss-process=style/watermark

# 六、Python2中代码

# 七、coding:gbk

x = '上'.decode('gbk')
y = '下'.decode('gbk')
print([x, y])  # [u'\u4e0a', u'\u4e0b']

7.0.2 Unicode类型

当Python解释器执行到产生字符串的代码时(例如s=u'林'),会申请新的内存地址,然后将'林'以Unicode的格式存放到新的内存空间中,所以s只能encode,不能decode。

# 八、Python2中代码

# 九、coding:gbk

x = u'上'  # 等同于 x='上'.decode('gbk')
y = u'下'  # 等同于 y='下'.decode('gbk')
print([x, y])  # [u'\u4e0a', u'\u4e0b']
print(type(x),type(y))  # (<type 'Unicode'>, <type 'Unicode'>)

对于print需要特别说明的是:当程序执行时,比如x='上' # gbk下,字符串存放为\xc9\xcf

print(x)这一步是将x指向的那块新的内存空间(非代码所在的内存空间)中的内存,打印到终端,按理说应该是存的什么就打印什么,但打印\xc9\xcf,对一些不熟知Python编码的程序员,立马就懵逼了,所以龟叔自作主张,在print(x)时,使用终端的编码格式,将内存中的\xc9\xcf转成字符显示,此时就需要终端编码必须为gbk,否则无法正常显示原内容:上。

047-Python2与3字符编码的区别上1.png?x-oss-process=style/watermark

047-Python2与3字符编码的区别-上2.png?x-oss-process=style/watermark

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

047-Python2与3字符编码的区别-上3.png?x-oss-process=style/watermark

047-Python2与3字符编码的区别-上4.png?x-oss-process=style/watermark

Unicode这么好,不会乱码,那Python2为何还那么别扭,搞一个str出来呢?Python诞生之时,Unicode并未像今天这样普及,很明显,好的东西你能看得见,龟叔早就看见了,龟叔在Python3中将str直接存成Unicode,我们定义一个str,无需是否加u前缀,就是一个Unicode,屌不屌?

9.1 Python3

Python3中str都是Unicode编码的,所以Python3中的str类型的数据可以编码成其他字符编码的格式,编码的结果为bytes类型。

# coding:gbk
x = '上'  # 当程序执行时,无需加u,'上'也会被以Unicode形式保存新的内存空间中,

print(f"type(x): {type(x)}")  # <class 'str'>

# x可以直接encode成任意编码格式
print(f"x.encode('gbk'): {x.encode('gbk')}")  # b'\xc9\xcf'
print(f"type(x.encode('gbk')): {type(x.encode('gbk'))}")  # <class 'bytes'>
type(x): <class 'str'>
x.encode('gbk'): b'\xc9\xcf'
type(x.encode('gbk')): <class 'bytes'>

很重要的一点是:看到Python3中x.encode('gbk') 的结果\xc9\xcf正是Python2中的str类型的值,而在Python3是bytes类型,在Python2中则是str类型。

文件的三种打开模式

件操作的基础模式有三种(默认的操作模式为r模式):

  • r模式为read
  • w模式为write
  • a模式为append

文件读写内容的格式有两种(默认的读写内容的模式为b模式):

  • t模式为text
  • b模式为bytes

需要注意的是:t、b这两种模式均不能单独使用,都需要与r/w/a之一连用。

一、文件打开模式之r模式

r: read,只读模式,只能读不能写,文件不存在时报错。

f = open('32.txt', mode='r')  # 报错
f.write()
f.close()
# rt: read by text
# windows的操作系统默认编码为gbk,因此需要使用utf8编码
f = open('32.txt', mode='rt', encoding='utf8')
data = f.read()
print(data)
print(f"type(data): {type(data)}")
f.close()
aaa
bbb
ccc
nick最帅吗
type(data): <class 'str'>
# rb: read by bytes
f = open('32.txt', mode='rb')
data = f.read()
print(data)
print(f"type(data): {type(data)}")
f.close()
b'aaa\nbbb\nccc\nnick\xe6\x9c\x80\xe5\xb8\x85\xe5\x90\x97'
type(data): <class 'bytes'>

f.read()读取文件指针会跑到文件的末端,如果再一次读取,读取的将是空格。

f = open('32.txt', mode='rt', encoding='utf8')
data1 = f.read()
data2 = f.read()
print(f"data1: {data1}")
print(f"data2: {data2}")
f.close()
data1: aaa
bbb
ccc
nick最帅吗
data2: 

Since all content f.read () one time to read the file, if the file is very large, it may cause memory ringing off the hook, that is, computer stuck. So you can use f.readline () / f.readlines () to read the file contents.

# f.readline()/f.readlines()
f = open('32.txt', mode='rt', encoding='utf8')
print(f"f.readable(): {f.readable()}")  # 判断文件是否可读
data1 = f.readline()
data2 = f.readlines()
print(f"data1: {data1}")
print(f"data2: {data2}")
f.close()
f.readable(): True
data1: aaa

data2: ['bbb\n', 'ccc\n', 'nick最帅吗']

Second, the open mode of the file mode w

w: only write, can not read, there is time to write the contents of the file back to the file and then emptied; file does not exist when the content is written after the file is created.

# wt
f = open('34w.txt', mode='wt', encoding='utf8')
print(f"f.readable(): {f.readable()}")
f.write('nick 真帅呀\n')  # '\n'是换行符
f.write('nick,nick, you drop, I drop.')
f.write('nick 帅的我五体投地')
f.flush()  # 立刻将文件内容从内存刷到硬盘
f.close()
f.readable(): False
# wb
f = open('34a.txt', mode='wb')
f.write('nick 帅的我五体投地'.encode('unicode_escape'))  # 编码成bytes类型
print(
    f"type('nick 帅的我五体投地'.encode('unicode_escape')): {type('nick 帅的我五体投地'.encode('unicode_escape'))}")
f.close()
type('nick 帅的我五体投地'.encode('unicode_escape')): <class 'bytes'>

Third, open the file mode of a mode

a: you can append. File exists, write to the end of the file; the file does not exist when the content is written after the file is created.

# at
f = open('34a.txt', mode='at', encoding='utf8')
print(f"f.readable(): {f.readable()}")
f.write('nick 真帅呀\n')  # '\n'是换行符
f.write('nick,nick, you drop, I drop.')
f.write('nick 帅的我五体投地')
f.close()
f.readable(): False

Fourth, read a binary file opened

b mode is a common pattern, because all the files on the hard disk is stored in binary form, needs attention

Guess you like

Origin www.cnblogs.com/TMesh-python/p/11316999.html