鱼C论坛

 找回密码
 立即注册
查看: 2303|回复: 7

Python3编码问题 (懂原理、明历史的大神请进~~)

[复制链接]
发表于 2018-5-30 19:48:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 kerwin_lui 于 2018-5-30 20:01 编辑

在爬虫过程中常常会被编码困扰,最近几天想啃下这块烦人的骨头,但是发现还有很多的问题,网上很多人对Python 编译器编码的讲解都不是很深入,貌似都是在自圆其说,看着都觉得不够合理,没有一个官方的定论,遂来求助鱼C,希望真正懂原理的大神可以不吝赐教!!!



问题一:
python3 默认编码格式到底是utf-8,还是unicode?   
网上有人说,Python3的文件编码是:utf-8 ;但是在内存里,python3编译器自动帮它转化成了unicode,而Python2不会自动转化成unicode,所以Python2写的代码即使申明了#coding=utf-8在win的cmd中运行时,中文还是会乱码(因为cmd是gbk编码的)

不知道以上的说法是否正确?到底是先编码成utf-8再转unicode,还是直接就将字符串编码成unicode,还是说字符串就是unicode?



问题二:
unicode到底是不是一种编码格式?
网上有人说,unicode只是一个巨大的字符集,它包含与全世界各个国家的字符集的映射,utf-8才是编码实现的一种方式。一个软件不管用什么编码,只要在该编码格式下转码成unicode,就可以在所有机器上正常显示任何字符

可是它也是一种二进制数啊,难道这不算编码?请问上述说法对吗?
另外,Python3中用 “\u9999” 表示 “香” 这个中文,这是否可以看出Python3 中的字符是用两个字节的 ucs-2 来表示?



问题三:
字符str类型,到底是什么?越学到后面,发现前面的知识根本没搞懂
python2中的str类型,貌似是包括bytes类型的,但是又有个unicode类型。
而Python3中没有了unicode类型,统称为str类型了........(傻傻分不清楚
例子说明:

【Python2】
代码:
  1. #coding=utf-8
  2. a = "小甲鱼"
  3. print(a)    #python2 中,a已经被utf-8编码,内存中以 '\xe5\xb0\x8f\xe7\x94\xb2\xe9\xb1\xbc' 表示 ,但是print()函数貌似可以在字符集自动寻找“\xe5\xb0\x8f”对应的字符,于是把“小”字显示在屏幕上了
  4. print(type(a))      
  5. b = a.decode("utf-8")   #通过“utf-8”将a这个bytes解码,变成unicode类型
  6. print(b)
  7. print(type(b))
复制代码

输出:
小甲鱼
<type 'str'>
小甲鱼
<type 'unicode'>

【python3】
代码:
  1. a1 = "小甲鱼"
  2. a2 = u'\u5c0f\u7532\u9c7c'
  3. print(a1)   #Python3 中,a1已经莫名其妙地变成了unicode,内存中以 u'\u5c0f\u7532\u9c7c' 表示,所以a1和a2貌似是等价的。  可是为什么等价呢,中间到底经历了什么?
  4. print(a2)
  5. print(type(a1))     #此时a1和a2都是str类型,那我可不可以认为python3中的str就是将中文字符已经编码成unicode了呢?
  6. print(type(a2))
  7. b = a1.encode("utf-8")    #此时把unicode编码成utf-8。   (可是上面已经把中文编码成了unicode,为什么这里又可以再编码成utf-8?)
  8. c = a1.encode("gbk")  
  9. print(b)
  10. print(type(b))   
  11. print(c)
  12. print(type(c))    #unicode是str类型,而utf-8、gbk都是bytes类型........为什么呢?  (python2中的print()函数可以自动寻找字符集,而这里不行,直接显示16进制数)
复制代码

输出:
小甲鱼
小甲鱼
<class 'str'>
<class 'str'>
b'\xe5\xb0\x8f\xe7\x94\xb2\xe9\xb1\xbc'
<class 'bytes'>
b'\xd0\xa1\xbc\xd7\xd3\xe3'
<class 'bytes'>

上述代码中的注释是我的猜想和疑惑,那么:
python3中的str类型和unicode的关系谁又能说清楚呢?



问题四:
python3编译器的执行过程会经历哪些步骤?
网上有人说,pyhton是解释型语言,不会像C一样生成一个二进制文件,且Python编译器是逐行解释

不生成二进制怎么存储??【黑人问号】
  1. s = "小甲"  #由于日本shift_jis的字符集中没有鱼字,遂只写“小甲”     
  2. print(s)
  3. with open("1.txt", "w", encoding = "shift-jis") as f:
  4.     f.write(s)
复制代码

将以上python代码命名为“test.py”,在linux的shell中用python3运行,编译器经历了哪几个步骤呢?

1、用vim写完上述代码,通过“:x” 保存退出,此时由于python3的默认文件编码是utf-8(相当于默认在头部写了“#coding:utf-8”)。所以该文件以文本的形式被utf-8编码成 “test.py” 文件存储在电脑硬盘中。
(电脑只认识01,必须编码才能存储)
2、在linux的shell中用python3运行 “test.py” 文件,由于linux的系统默认编码是utf-8,所以可以将test.py文件用utf-8解码,并进行逐行读取。但是win中cmd的默认编码是gbk,它也能解码读取,这就很奇怪了。[这个步骤我一定错得很离谱~~~]
3、将读取到的数据、函数、命令,进行词法分析、语法分析,然后根据机器指令集,翻译成机器能读懂的指令字节码放入内存,接着cpu进行“取指执行”。
(读到的数据若是字符串,那么就用utf-8编码,亦或者用unicode编码)
(注: 运行编译器时候的“编译”和字符的“编码”,应该是不同的概念~~)
4、编译器读到“print(s)”时,因为是python3的编译器编译的,所以不管是linux的shell,亦或者是win的cmd,都是可以正常显示的。(而在cmd中用Python2运行,就是乱码,我也不知道为什么)
5、编译器读到最后一行,将 “小甲” 这两个中文字符用日本的“shift-jis”格式编码成 “1.txt” 文本文件
6、此后,若要调取“1.txt” 中 “小甲” 这两个字,必须要申明 encoding="shift-jis” 。若写了encoding="gbk” ,或者干脆不写,都会显示 “彫峛” 这样的乱码;但若写了encoding="utf-8”,则更悲催的报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8f in position 0: invalid start byte
(这里又让我感到奇怪,python3不是默认utf-8编码吗?为啥不写encoding的结果与encoding="gbk” 时候一样???)

以上,是我的猜测,有些地方难以自圆其说,肯定存在很多问题,求指教!!


————————————————————丑陋分割线 ———————————————————


码字码着码着,感觉很多概念又混在一起了,这滋味......

真的想把它搞懂,问的问题比较多,不知道大神们能不能理解我的困惑?
#如果可以解决我的烦恼,可以支付宝转账感谢~~~


如果嫌问题多,可以抽一个回答下哦~~~~感谢!!!!
111.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-5-30 20:58:25 | 显示全部楼层
说实话,编码问题我也是从来一知半解,直到有一次批量爬美女图片的时候,它网页上的charset写的是gb2312,我上网上查,怎么都弄不好这个编码。。。。帮顶
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2018-5-30 21:47:10 | 显示全部楼层
溯影 发表于 2018-5-30 20:58
说实话,编码问题我也是从来一知半解,直到有一次批量爬美女图片的时候,它网页上的charset写的是gb2312, ...

哈哈,感谢,这个问题真的会像幽灵般纠缠着....
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-2 18:19:23 | 显示全部楼层
突然想到这个帖子,最近写了篇东西,或许可以帮到你~
https://mp.weixin.qq.com/s/JxD7LC33zbFD5QBxJ6jMWw

python3 默认编码格式到底是utf-8,还是unicode?  
看用在什么地方,读取文件的时候默认编码格式就是utf-8,字符串在Python内部的表示是unicode编码。
字符串在Python内部的表示是unicode编码
可以参考知乎:https://www.zhihu.com/question/23374078
python3编译器的执行过程会经历哪些步骤?
我文章里有写~~~
至于第三个问题,str和Unicode的关系???不知道什么意思。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-19 16:00:57 | 显示全部楼层
Charles未晞 发表于 2018-8-2 18:19
突然想到这个帖子,最近写了篇东西,或许可以帮到你~
https://mp.weixin.qq.com/s/JxD7LC33zbFD5QBxJ6jMWw ...

哈哈,感谢了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-19 16:09:30 | 显示全部楼层
Charles未晞 发表于 2018-8-2 18:19
突然想到这个帖子,最近写了篇东西,或许可以帮到你~
https://mp.weixin.qq.com/s/JxD7LC33zbFD5QBxJ6jMWw ...

我刚刚又碰到了一个新问题,能否帮忙看看,嘿嘿~~~
https://fishc.com.cn/thread-120704-1-1.html
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-19 22:41:23 | 显示全部楼层
kerwin_lui 发表于 2018-8-19 16:09
我刚刚又碰到了一个新问题,能否帮忙看看,嘿嘿~~~
https://fishc.com.cn/thread-120704-1-1.html

Emmmm,最近不常上鱼C了~~~或许可以邮箱交流
Charlesjzc@qq.com
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-20 03:41:32 | 显示全部楼层
Charles未晞 发表于 2018-8-19 22:41
Emmmm,最近不常上鱼C了~~~或许可以邮箱交流

哈哈哈,好哒
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-12-30 12:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表