宋立赢 发表于 2020-6-14 20:03:27

有关编码与解码的问题

想知道open里的encoding具体是怎么编码的,例如是不是把txt文本的内容用encoding = gbk或者=utf-8等方式编码,那既然有编码,那解码在哪体现,还有那种报错,例如 'gbk'codec can't decode byte......等这种报错,一般换成utf-8就能解决,但是why?docode是解码有关的,解码出问题了?或许f.read()是个解码方式?报错的本质原因是什么?把'gbk'换成‘utf-8’是更换了编码方式么,这么改或许是因为解码方式不是'gbk'?,是'utf-8'?但是好像'gbk'和'utf-8'是编码方式,能作为解码方式么?以上问题求解{:5_99:}

Twilight6 发表于 2020-6-14 20:03:28



想知道open里的encoding具体是怎么编码的,例如是不是把txt文本的内容用encoding = gbk或者=utf-8等方式编码
open刚刚开始打开一个文件,既不对他编码也不对他解码,因为从报错就可以看出来,只有你 read() 的时候报错 xxx 码无法解码 xxx

那么就说明当你 read 的时候才开始解码,如果一开始就进行解码,那么报错应该是在创建文件对象的一瞬间,而不是创建后的read()

那既然有编码,那解码在哪体现
写入时候,体现编码吧,解码体现在你读取文件内容的时候

还有那种报错,例如 'gbk'codec can't decode byte......等这种报错,一般换成utf-8就能解决,但是why?
不知道你有没发现,当文本内只有英文时候居然不会报解码错误的报错?这是为什么呢?

这是因为 GBK 和 UTF-8 解码英文或数字时候都是以一个字节编码格式写入的,解码时候也是以一个字节,因为解码和编码一一对应所以不会报错

那么为什么中文会报错呢?

就是因为 GBK 编码中文时候大部分汉字的字节为 2而UTF-8 在编码汉字时候大于 2,导致如果你是以 GBK 写入的,用UTF-8读取解码就会出错,因为解码和编码字节要一一对应才能成功解码

docode是解码有关的,解码出问题了?或许f.read()是个解码方式?
首先你打错了,是decode,decode的作用是将其他编码的字符串转换成unicode编码

f.read() 是读取文件内容,解码的事情交给你开始时候open 设定的解码方式

报错的本质原因是什么?把'gbk'换成‘utf-8’是更换了编码方式么,这么改或许是因为解码方式不是'gbk'?,是'utf-8'?但是好像'gbk'和'utf-8'是编码方式,能作为解码方式么?

看了上面的解释你应该有个简单的认识了,这个问题用上面的答案就可以解决,编码是什么编码的,就应当要用什么解码比较合适滴~



在这里推荐你看个科普小视频,讲的非常好,强力推荐:

见过电脑里的乱码吗,这比你想象得要深很多



ba21 发表于 2020-6-14 20:18:34

用第三方库,要不就自己写复杂的代码判断
检测文件编码

import cchardet as chardet

# 先检测出文件编码
with open("test.txt", "rb") as f:
    msg = f.read()

enc = chardet.detect(msg) # 返回的是个字典 编码和准确度。如:{'encoding': 'UTF-8', 'confidence': 0.9900000095367432}
print(enc)
enc = enc['encoding']

# 然后以指定编码打开文件
with open("test.txt", "r", encoding=enc) as f:
    print(f.read())
网页编码判断

import requests
import cchardet

res = requests.get('http://www.baidu.com/')
rawdata= res.content
enc = cchardet.detect(rawdata)
enc = enc['encoding']
print(enc)

BIO-张磊 发表于 2020-6-14 20:23:43

本帖最后由 BIO-张磊 于 2020-6-14 21:18 编辑

encoding是指 你的文件是用什么编码的,是既定事实,你open它。encoding就像一把钥匙,你的文件用GBK编码需要GBK钥匙,那就输入GBK,用UTF-8编码就需要UTF-8要是,那就输入UTF-8
但是计算机存储的时候是根据你的编码方式转换成的二进制,你能看到它,只是因为解码成功了
具体看下面的例子

BIO-张磊 发表于 2020-6-14 21:01:59

本帖最后由 BIO-张磊 于 2020-6-14 21:22 编辑

我在举个例子吧
str1 = "小甲鱼"
str1_GBK = str1.encode("GBK")###结果是bytes对象b'\xd0\xa1\xbc\xd7\xd3\xe3'
str1_UTF8 = str.encode("UTF-8")###结果是bytes对象 b'\xe5\xb0\x8f\xe7\x94\xb2\xe9\xb1\xbc'

str1_GBK.decode()#python默认是UTF-8解码,所以会报错'utf-8' codec can't decode byte 0xbc.....
str1_UTF8.decode()#会返回正确结果

str1_GBK.decode(encoding = "GBK")#会返回正确结果
str1_UTF8.decode(encoding = "GBK")#会报错

所以你读进去的时候,你指定encoding,你解码的时候,他会根据你指定的encoding对这个bytes对象进行解码
所以这中间有个bytes对象作为媒介
前后不一致,当然会报错,因为可能A编码转化成的bytes对象,以B编码去解码就识别不了这个bytes对象。

桃丶 发表于 2020-6-14 21:05:09

gbk方式一个汉字占两个字节
utf8方式一个汉字占3个字节
如果用gbk方式字节流读入 ,用utf8写出 会导致字节长度不对应 从而中文出现乱码

_荟桐_ 发表于 2020-6-14 21:18:18

用什么方式编码就用什么方式解码

因为计算机里只能存0100010010
所以就要把文字编成0100010010101
就有了编码,
读取就要把文件解码

open函数里写了encoding="utf-8"就是用utf8解码文件
如果用其它方式会报错"utf-8"codec can't decode ......

因为一般文件都是用utf8编码的,所以一般都用utf8解码

f.read不是解码

utf8和gbk是编码方式,但可以逆着解码
就像一句话可以翻译成英语,但也可以再翻回来

宋立赢 发表于 2020-6-15 08:07:54

Twilight6 发表于 2020-6-14 22:45
open刚刚开始打开一个文件,既不对他编码也不对他解码,因为从报错就可以看出来,只有你 read() 的 ...

既然f.read()是解码,那比如读取一个文件的内容的时候,既然解码,那肯定先有编码吧,这个编码是不是就在txt文本内进行了,就是说在文本内写入文字时,txt文本就对文字以某种方式编码(比如用gbk编码,而read的时候就用encoding的utf-8解码,从而报错),那这某种方式是默认的还是由什么其他决定的,通常报错你说因为解码和编码方式不一致,这时候我们可以改变解码方式,那编码方式能改嘛?在哪改?这是最后的疑问,麻烦你了

Twilight6 发表于 2020-6-15 08:38:08

本帖最后由 Twilight6 于 2020-6-15 08:43 编辑

宋立赢 发表于 2020-6-15 08:07
既然f.read()是解码,那比如读取一个文件的内容的时候,既然解码,那肯定先有编码吧,这个编码是不是就在 ...



既然f.read()是解码,那比如读取一个文件的内容的时候,既然解码,那肯定先有编码吧,这个编码是不是就在txt文本内进行了
解码就是把已经编码好的文件给解码开,编码是当你写入文件内容时候才算编码

简单理解 txt 文本创建,你写入内容,这就算编码过程,txt文本显示给你看,这就是解码过程

就是说在文本内写入文字时,txt文本就对文字以某种方式编码(比如用gbk编码,而read的时候就用encoding的utf-8解码,从而报错)

上面一楼已经回答了这个问题,简说是因为不同的编码,编码一个字符时字符所占字节不同,导致不同解码过程中解码字节数与编码前不同

导致报错,你英文就不会报错,因为英文这两种编码都是一个字节,编码时候这个字符是几个字节,解码时候就要按照这个字节来,才可正常解码


那编码方式能改嘛?在哪改?
第一步:
https://xxx.ilovefishc.com/forum/202005/25/072650zqq1fqqmng421bqz.jpg
第二步:
https://xxx.ilovefishc.com/forum/202005/25/072647nvzjv2zemvgxet5g.jpg

宋立赢 发表于 2020-6-15 09:13:29

Twilight6 发表于 2020-6-15 08:38
解码就是把已经编码好的文件给解码开,编码是当你写入文件内容时候才算编码

简单理解 txt 文 ...

好的好的知道了{:5_110:}
页: [1]
查看完整版本: 有关编码与解码的问题