请原谅这个问题:
我用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? p>
在2.x中处理所有上述问题的常用方法是什么? from __future__ import unicode_literals
声明?
不好意思成为一个这样的菜鸟,但这改变了我长期以来一直在做的事情,很明显我很困惑。
答案 0 :(得分:14)
“始终使用Unicode”建议主要是为了更轻松地过渡到Python 3。如果你的代码中有很多非Unicode字符串访问,那么移植它需要做更多的工作。
此外,您不必根据具体情况决定字符串是否应存储为Unicode。您不必更改字符串的类型及其语法,只是因为您更改了其内容。
使用错误的字符串类型也很容易,导致主要工作的代码,或者在Linux中但不在Windows中工作的代码,或者在一个区域设置中但不在另一个区域中的代码。例如,UTF-8语言环境中的for c in "漢字"
将遍历每个UTF-8字节(所有六个字节),而不是遍历每个字符;是否打破了事情取决于你对他们做了什么。
原则上,如果你使用Unicode字符串,什么都不应该破坏,但如果你不使用常规字符串,事情可能会中断。
然而,在实践中,在Python 2中使用Unicode字符串是一件痛苦的事。codecs.open
没有自动选择正确的语言环境;这失败了:
codecs.open("blar.txt", "w").write(u"漢字")
真正的答案是:
import locale, codecs
lang, encoding = locale.getdefaultlocale()
codecs.open("blar.txt", "w", encoding).write(u"漢字")
...这很麻烦,迫使人们只是打开文件来制作辅助功能。 codecs.open
应该在未指定时自动使用locale
中的编码; Python无法使这么简单的操作变得方便,这是人们通常不在任何地方使用Unicode的原因之一。
最后请注意,在某些情况下,Unicode字符串在Windows中更为重要。例如,如果您使用的是西部语言环境,并且您有一个名为“汉字”的文件,则必须使用Unicode字符串来访问它,例如。 os.stat(u"漢字")
。使用非Unicode字符串访问它是不可能的;它只是看不到文件。
所以,原则上我会说Unicode字符串推荐是合理的,但有一点需要注意,我自己一般都不遵循它。
答案 1 :(得分:11)
不,不是每个字符串“都应该是Unicode”。在你的Python代码中,你知道字符串文字是否需要是Unicode,所以将每个字符串文字都变成Unicode文字没有任何意义。
但是有些情况下你应该使用Unicode。例如,如果您有任意文本输入,请使用Unicode。你迟早会找到一个使用它的非美国人,而且他想在这里找到一个非常好的人。除非您的输入和输出碰巧使用相同的编码,否则您将遇到问题,这是您无法确定的。
所以简而言之,不,字符串不应该是Unicode。 文字应该是。但是YMMV。
具体做法是:
此处无需使用Unicode。您知道该字符串是否为ASCII。
取决于您是否需要将这些字符串与Unicode合并。
两种方式都有效。但是不要在需要时编码解码。解码ASAP,尽可能晚编码。使用编解码器可以很好地工作(或者从Python 2.7开始)。
呀。
答案 2 :(得分:6)
恕我直言(我的简单规则):
我应该这样做:
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')
- 读取/写入文件时,我应该使用编解码器模块。对?或者我应该在需要时使用标准方式或读/写和编码或解码?
醇>
如果您希望使用unicode文本,请使用编解码器。
- 如果我从raw_input()获取字符串,我是否应该将其转换为Unicode? li> 醇>
仅当您期望可能转换到具有不同默认编码的另一个系统(包括数据库)的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
因此,如果将包含utf-8(或其他非ascii char)的字节字符串与unicode文本混合而不进行显式转换,则会遇到问题,因为默认情况下为ascii。另一种方式似乎是安全的。如果遵循将包含非ascii的每个字符串写为unicode文字的规则,那么你应该没问题。
免责声明:我住在巴西,人们会说葡萄牙语,这是一种含有大量非ascii字符的语言。我的默认编码始终设置为'utf-8'。您的里程可能因英语/ ascii系统而异。
答案 3 :(得分:3)
我只是在这里添加我的个人意见。在其他答案中没有那么长并且详细说明,但也许它也可以提供帮助。
print u'Some text'
或仅print 'Text'
?
我确实更喜欢第一个。如果您知道只有Unicode字符串,则会有一个不变量。各种其他语言(C,C ++,Perl,PHP,Ruby,Lua,...)有时会遇到痛苦的问题,因为它们在代码单元序列和整数序列之间缺乏分离。我发现在.NET,Java,Python等中存在严格区分的方法相当简洁。
一切都应该是Unicode,这是否意味着,比如说我有一个元组:
t = ('First', 'Second')
,应为t = (u'First', u'Second')?
是
我读到我可以做一个
from __future__ import unicode_literals
,然后每个字符串都是一个Unicode字符串,但是我也应该在容器内执行此操作吗?
是。将来的语句仅适用于使用它们的文件,因此您可以在不干扰其他模块的情况下使用它们。我通常会导入Python 2.x模块中的所有期货,以便更容易过渡到3.x.
在读取/写入文件时,我应该使用
codecs
模块。对?或者我应该在需要时使用标准方式或读/写和编码或解码?
您应该使用codecs
模块,因为这使得不可能(或至少非常难)意外地将不同编码的表示写入单个文件。当您以文本模式打开文件时,它也是Python 3.x的工作方式。
如果我从说
raw_input()
获取字符串,我是否应该将其转换为Unicode? p>
我也对此说“是”:在大多数情况下,只处理一种编码更容易,所以我建议尽早转换为Python Unicode字符串。
在2.x中处理所有上述问题的常用方法是什么?
from __future__ import unicode_literals
声明?
我不知道常见的方法是什么,但我一直都在使用这种说法。我在这种方法中遇到的问题很少,而且大多数都与外部库中的错误有关 - 即,NumPy有时需要字节字符串而不记录它。
答案 4 :(得分:2)
在遇到有关Unicode的任何内容之前,您在编写Python代码6个月这一事实意味着字符串的Python 2.x ASCII默认值不会导致任何问题。当然,初学者试图掌握Unicode /代码点/编码本身的想法是一个难以解决的问题;因此,大多数教程自然会绕过它,直到你在基础知识中获得更多的基础。这就是为什么在像Dive Into Python这样的书中,只提到了in later chapters。
如果您需要在应用程序中支持Unicode,我建议您查看Kumar McMillan's PyCon 2008 talk on Unicode以获取最佳做法列表。它应该回答你剩下的问题。
答案 5 :(得分:-2)
1/2)就我个人而言,我从未听说过“总是使用unicode”。这对我来说似乎很愚蠢。我想我明白你是否打算支持其他需要unicode支持的语言。但除此之外我不会这样做,看起来更像是一种痛苦而不是它的价值。
3)我只需读取/写入标准方式并在必要时进行编码。