前几天看了那篇讲 unicode pain 的文章,感觉很理解了,unicode sandwish:要输出的时候转 bytes,程序里统一用 unicode。
但今天码作的时候写着写着突然发现我可以用中文声明一个变量,然后输出到文件
zhongwen = ['中文','你好']
with open('test.txt','w') as f:
f.writelines(zhongwen)
那干嘛还要 unicode 或者说 unicdoe type 这个东西?通篇用字节类型不就行了? 字符串操作, str(py2), bytes(py3)一样都能 strip()。
请打脸,大脸必重谢。(严肃脸)
1
yksoft1 2017-08-17 14:13:17 +08:00
问题是 python 默认的字符串内码和平台有关,和系统有关。
|
2
ysc3839 2017-08-17 14:16:53 +08:00 via Android 1
是可以不要 Unicode,Unicode 实际上也是一堆 bytes,弄这个只是为了方便处理。
|
3
rebeccaMyKid OP @yksoft1 这么讲太高深了。。。完全没概念
|
4
rebeccaMyKid OP @ysc3839 对啊, 不知道其他语言是怎么样处理的。我能想到一点的就是,在做字符串操作的时候,可能需要这 unicode 或者说 str(py3)这种类型,比如说 a = u'中文', a[0] == u'中',但 b = '中文', b[0] 这个就是 code points 了。除此之外想不到其他的,这里面的细节我也是很清楚,就是觉得有点迷。
|
5
glasslion 2017-08-17 14:27:36 +08:00 1
字节是和编码相关的, 用户有不一定都是 utf-8 编码
|
6
rebeccaMyKid OP 打错:这里面的细节我也不是很清楚
|
7
ysc3839 2017-08-17 14:29:09 +08:00 via Android 1
@ysc3839 至于方便在哪,大概是不用考虑多字节的问题吧,比如 UTF-16 一个字符一般是两个字节,自己处理的话就不能直接一个个来读取了,得读取两个。
另外在调用一些函数的时候,如果直接传 Unicode,那函数就可以根据系统来直接编码成对应的 bytes。如果传 bytes 进去的话,还得指定是什么编码,函数内部再转换。 |
8
ysc3839 2017-08-17 14:31:30 +08:00 via Android
@rebeccaMyKid 其他语言的话,C++ 有 UTF-16 UTF-32 对应的类型。还有个平台相关的 wchar_t ( Windows 下是 UTF-16,*nix 下是 UTF-32 )。
|
9
BOYPT 2017-08-17 14:32:19 +08:00 1
主要问题是你的源码文件也是有编码的,utf8 的源码文件还是 GBK 的?这处理起来就不一样了。
最终都还是要理解透编码。 |
10
rebeccaMyKid OP @BOYPT 哇,小白 dig 不下去了呀。说得太简略了
|
11
BOYPT 2017-08-17 15:01:01 +08:00 2
@rebeccaMyKid #10 编码问题,归结下来有这几个地方需要注意:
输入编码 - 处理过程 - 输出编码 - 显示编码 输入编码是指,你获取的信息来源,比如从数据库里、文件里、网页里、源文件里,获取的是输入的数据,要让程序正确低读取出这些数据; python3 里,"中文"和 u"中文"是等价的,而.py 文件如无意外是 utf-8 编码的,这时候就是一个隐式的 utf-8 到 unicode 的转换了。如果文件编码不是 utf-8,是需要在源码前写#coding: GBK 这样的声名,说这个文件是 GBK 编码的; python2 时候,如果没声名 utf-8,,在源码里写中文是会报错的,因为默认了 ascii 编码而已。 处理过程,在 python 里的话用 Unicode 串最方便了,因为方便后续处理;其他语言有些是没有宽字节类型的比如 php,就用 utf-8。 输出编码,一般需要根据你输出的地方,把处理过程中的字符处理成合适的编码;这一点在 python 里很多时候是隐式处理的,意思就是,直接给输出接口喂 Unicode 的东西,自动封装来编码过程;例子就是,print(u'中文')跟 print("中文".encode('utf-8'))其实是两个处理方式了。 显示编码,根据使用环境,不一定是 python 的问题;比如 python 输出 web 页面,需要设置 HTTP Header 声名编码、Html META 声名,然后浏览器才能正确解释出内容,否则也是乱码。极端例子是在 windows 的命令符使用 python,直接 print(u'中文') 会出现 unicode 无法显示的问题,因为,中文 Windows 的终端是 GBK 的,print()输出时候没法编码正确。 其实所有语言处理编码都是这几个关键点。 |
12
SuperMild 2017-08-17 15:01:23 +08:00 via iPhone
假设你在 win 下用该代码写文件,系统默认 gbk 编码,后来在 linux 上读取该文件,系统默认 utf8,读取失败!
|
13
wwqgtxx 2017-08-17 15:02:04 +08:00 via iPhone
说到底,utf8 并不是唯一的编码格式,而 bytes 保存的并不一定就是 utf8 编码的数据,也有可能是 utf16,utf32 等等,比如 u"aaa".encode("utf16be")你试试输出什么结果
|
14
rebeccaMyKid OP 编码的问题我懂。。但我没看懂编码的问题跟我这个问题有什么联系。。我还是觉得
@ysc3839 跟我想的差不多。 另外我也在 stackoverflow 上提了这问题,觉得答案也是跟我想的差不多,https://stackoverflow.com/questions/45728178/why-do-python-need-unicode-type-since-i-can-declare-a-variable-directly-with-any/45728222#45728222,结题吧,谢谢各位。 |
15
wzha2008 2017-08-17 15:33:16 +08:00 1
我就举一个例子:
>> print len('啊') >> 3 >> print len(u'啊') >> 1 |
16
rebeccaMyKid OP 我觉得里面有句话说得很有意思,就是“ Text is text and bytes are bytes.”。我理解这句话是说,其实都是字节,但 text 是从 bytes 抽象出来的给人看的东西,len(字节) 跟 len(字符),后者这种对于字符的操作,才对我们( human )使用者有意义,我猜这是这种类型存在的理由(之一?)。
(如果全世界的字符都能只用一个 byte 编码,可能就不需要这种类型了?)。 已经学到东西拉,不 dig 了,谢谢各位 :D |
17
rebeccaMyKid OP @wzha2008
哈哈哈,对对对,我就是这么想的。只是 po 出来想问问还有其他什么原因没:D |
18
rebeccaMyKid OP @BOYPT 这个看懂了,谢谢老哥。
|