@
dousao 呃,之前读了一遍觉得有的地方有点乱,不知该从哪说起。
我又看了遍文章,指出一些我和作者理解不同的地方。
1. 「 Str 表示的是字符串,拥有编码类型, Bytes 表示的是字节流,没有编码类型。」
这句话三楼也指出问题了: Python 3 中的 str 字符串是 Unicode ,存储的是 code points (码点),是没有编码的;而 bytes 相当于 Python 2 的 str ,自身是有编码的。
2. 「当我们创建一个新的字符串的时候,字符串会有一个指定编码,既 Python 认为这个字符串是以什么编码来存储的, Python 默认的指定编码我们可以用 sys.getdefaultencoding()函数来获取到」
sys.getdefaultencoding() 是 Python 的默认编码没错。但是创建新字符串时,字符串的编码和 Python 的默认编码没太大关系。如果字符串是从终端输入的,字符串编码是由终端编码来决定的;如果字符串是写在源码里或者从文件读取的,字符串编码是由文件编码决定的;如果字符串是从网页抓来的,字符串编码是由网页编码决定的。
Python 2 存储的就是原始编码的字符串; Python 3 会将原始字符串用判断出的编码或用户提供的编码来转换为 Unicode 字符串,只有在无法判断出编码时或用户没提供编码时才会用 sys.getdefaultencoding() 的默认编码来转换。
3. 「但是呢,字符串的实际编码并不是说 Python 指定了哪个就是哪个了,这个和系统的默认编码有关」
你这里说的「实际编码」指的是什么?是做什么用的?我没理解。
4. 「而返回的 unicode 对象的默认编码是 utf-8 。」
同上, unicode 对象是没有编码的,你可以用任何支持的编码将 unicode 对象转换为 str 对象,所以不能说 unicode 对象的默认编码是 utf-8 。
5. 「这是因为 Python 写入文件的时候将 Unicode 自动转换成了 Str ,然后这个 Str 的指定编码为 ascii ,但是实际内容却是以 utf-8 来编码的汉字,结果就是抛出编码异常了。」
这句话表述有点问题: Unicode 是没有编码的,所以不能说实际内容是以 utf-8 来编码的汉字。实际上除了 utf-8 编码,你也可以用 gbk 等编码将 unicode 的汉字转换为 str 字符串。而这里因为默认使用的 ascii 编码无法对有汉字的 unicode 字符串进行编码,所以抛出异常了。
6. 「更改 Python 默认的指定编码」
不提倡的解决方法,相关阅读:
https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes /t/163786以上仅是个人理解,不一定都是对的。