use*_*312 22 python unicode bytestring
原谅如果这是一个很长的问题:
我用Python编程了大约六个月.自学,从Python教程开始,然后是SO,然后只使用谷歌的东西.
这是悲伤的部分:没有人告诉我所有字符串都应该是Unicode.不,我不是在撒谎或说谎,但教程在哪里提到它?我也看到大多数示例只是使用byte strings,而不是Unicode strings.我只是浏览并在SO上遇到这个问题,它说明Python中的每个字符串应该是一个Unicode字符串.这让我哭了!
我读到默认情况下Python 3.0中的每个字符串都是Unicode,所以我的问题是2.x:
我应该这样做:
print u'Some text'还是只是print
'Text'?
一切都应该是Unicode,这是否意味着,就像说我有一个tuple:
t = ('First', 'Second'), it should be t = (u'First', u'Second')?
我读过我可以做一个from __future__ import unicode_literals然后每个字符串都是一个Unicode字符串,但是我应该在容器内执行此操作吗?
读/写文件时,我应该使用该codecs模块.对?或者我应该使用标准方式或阅读/写作和/ encode或decode在需要的地方?
如果我从中获取字符串raw_input(),我应该将其转换为Unicode吗?
在2.x中处理所有上述问题的常用方法是什么?该from __future__ import unicode_literals声明?
对不起是一个这样的菜鸟,但这改变了我长期以来一直在做的事情,所以我很困惑.
Gle*_*ard 14
"始终使用Unicode"建议主要是为了更容易地过渡到Python 3.如果你的代码中有很多非Unicode字符串访问,那么移植它需要更多的工作.
此外,您不必根据具体情况决定字符串是否应存储为Unicode.您不必更改字符串的类型及其语法,因为您也改变了它们的内容.
使用错误的字符串类型也很容易,导致代码主要工作,或者代码在Linux中运行但不在Windows中运行,或者在一个语言环境中运行,而不是在另一个语言环境中运行.例如,for c in "??"在UTF-8语言环境中,将迭代每个UTF-8字节(所有六个字节),而不是每个字符; 是否打破了事情取决于你对他们做了什么.
原则上,如果你使用Unicode字符串,什么都不应该破坏,但如果你不应该使用常规字符串,事情可能会中断.
然而,在实践中,在Python 2 codecs.open中使用Unicode字符串是一种痛苦. 不会自动选择正确的语言环境; 这失败了:
codecs.open("blar.txt", "w").write(u"??")
Run Code Online (Sandbox Code Playgroud)
真正的答案是:
import locale, codecs
lang, encoding = locale.getdefaultlocale()
codecs.open("blar.txt", "w", encoding).write(u"??")
Run Code Online (Sandbox Code Playgroud)
...这很麻烦,迫使人们只是打开文件来制作辅助功能. codecs.open 应该在locale没有指定时自动使用编码; Python无法使这么简单的操作变得方便,这是人们通常不在任何地方使用Unicode 的原因之一.
最后,请注意在某些情况下,Unicode字符串在Windows中更为重要.例如,如果您使用的是西部语言环境,并且您有一个名为"汉字"的文件,则必须使用Unicode字符串来访问它,例如.os.stat(u"??").使用非Unicode字符串访问它是不可能的; 它只是看不到文件.
因此,原则上我会说Unicode字符串建议是合理的,但有一点需要注意,我自己一般都不遵循它.
Len*_*bro 11
不,不是每个字符串"都应该是Unicode".在Python代码中,您知道字符串文字是否需要是Unicode,因此将每个字符串文字都设置为Unicode文字没有任何意义.
但是有些情况下你应该使用Unicode.例如,如果您有任意文本输入,请使用Unicode.你迟早会找到一个使用它的非美国人,而且他想在这里找到一个非常好的人.除非您的输入和输出碰巧使用相同的编码,否则您将遇到问题,这是您无法确定的.
所以简而言之,不,字符串不应该是Unicode.文字应该是.但是YMMV.
特别:
这里不需要使用Unicode.您知道该字符串是否为ASCII.
取决于您是否需要将这些字符串与Unicode合并.
两种方式都有效.但是不要在需要时编码解码.解码ASAP,尽可能晚编码.使用编解码器可以很好地工作(或者从Python 2.7开始).
是啊.
恕我直言(我的简单规则):
我应该这样做
print u'Some text' or just print 'Text'吗?一切都应该是Unicode,这是否意味着,就像说我有一个元组:
t = ('First', 'Second'), it should be t = (u'First', u'Second')?
好吧,只有当我有一些高于ASCII 128的字符时才使用unicode文字:
print 'New York', u'São Paulo'
t = ('New York', u'São Paulo')
Run Code Online (Sandbox Code Playgroud)
- 在读/写文件时,我应该使用编解码器模块.对?或者我应该只使用标准方式或读/写和编码或解码所需的?
如果您期望unicode文本,请使用编解码器.
- 如果我从raw_input()获取字符串,我是否应该将其转换为Unicode?
仅当您期望可能转换到具有不同默认编码的另一个系统(包括数据库)的unicode文本时.
EDITED(关于混合unicode和字节串):
>>> print 'New York', 'to', u'São Paulo'
New York to São Paulo
>>> print 'New York' + ' to ' + u'São Paulo'
New York to São Paulo
>>> print "Côte d'Azur" + ' to ' + u'São Paulo'
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1:
ordinal not in range(128)
>>> print "Côte d'Azur".decode('utf-8') + ' to ' + u'São Paulo'
Côte d'Azur to São Paulo
Run Code Online (Sandbox Code Playgroud)
因此,如果将包含utf-8(或其他非ascii char)的字节字符串与unicode文本混合而不进行显式转换,则会遇到问题,因为默认值为ascii.另一种方式似乎是安全的.如果遵循将包含非ascii的每个字符串写为unicode文字的规则,那么你应该没问题.
免责声明:我住在巴西,人们会说葡萄牙语,这是一种含有大量非ascii字符的语言.我的默认编码始终设置为'utf-8'.您的里程可能因英语/ ascii系统而异.