我所知道的是:
# -*- coding: utf-8 -*-
它用于声明Python源文件的编码,一旦我设置了编码名称,Python解析器将使用给定的编码解释文件。我称之为“文件编码”;
from __future__ import unicode_literals
我正在使用Python2.7完成任务,并使用from __future__ import unicode_literals
将字符串的默认类型从“str”更改为“unicode”。我称之为“字符串编码”;
sys.setdefaultencoding('utf8')
但有时,我在Django中出现错误,例如,我在管理员中存储了中文,然后我访问了相关的页面
/ admin / blog / vulpaper / 29 / change /
的UnicodeEncodeError 'ascii'编解码器无法编码位置6-13中的字符:序数不在范围(128)中 ....错误信息越多 无法编码/解码的字符串是:emcms外贸网站管理系统
对于这个问题,我将在Django设置文件中编写sys.setdefaultencoding('utf8')
来解决它。
但实际上,我不知道上述技术细节。
令我困惑的是:
1.由于我设置了python源文件编码,为什么要设置字符串编码以确保我的字符串编码是我最喜欢的编码?
“文件编码”和“字符串编码”有什么不同?
2.由于我设置了“文件编码”和“字符串编码”,为什么还会发生UnicodeEncodeError?
答案 0 :(得分:2)
通常,您必须同时使用file encoding
和literal strings encoding
,但它们实际上控制的是非常不同,并且有助于了解它们之间的区别。
如果您希望在源代码中的任何地方(例如注释或文字字符串)写入unicode字符,则需要更改编码以使python解析器正常工作。设置错误的编码将导致SyntaxError
异常。 PEP 263详细说明了该问题以及如何控制解析器的编码。
在Python 2.1中,只能使用Latin-1编写Unicode文字 基于编码的“ unicode-escape”。这使得编程 环境对居住和工作的Python用户而言并不友好 非拉丁1区域设置,例如许多亚洲国家/地区。
...
如果未提供其他编码提示,Python将默认使用ASCII作为标准编码。
Python 2对字符串使用两种不同的类型,unicode
和str
。当您定义文字字符串时,解释器实际上会创建一个保存该文字的str
类型的新对象。
s = "A literal string"
print type(s)
<type 'str'>
TL; DR
如果您想更改此行为并在每次定义无前缀字符串文字时创建
unicode
对象,则可以使用from __future__ import unicode_literals
如果您需要了解为什么这样做有用,请继续阅读。
您可以使用u
前缀将文字字符串显式定义为unicode。解释器将代替为此文字创建一个unicode
对象。
s = u"A literal string"
print type(s)
<type 'unicode'>
对于ASCII文本,使用str
类型就足够了,但是如果要处理非ASCII文本,则使用unicode
类型使字符级操作正常工作很重要正确地。以下示例显示了对于完全相同的文字,使用str
和unicode
进行字符级解释的区别。
# -*- coding: utf-8 -*-
def print_characters(s):
print "String of type {}".format(type(s))
print " Length: {} ".format(len(s))
print " Characters: " ,
for c in s:
print c,
print
print
u_lit = u"Γειά σου κόσμε"
s_lit = "Γειά σου κόσμε"
print_characters(u_lit)
print_characters(s_lit)
输出:
String of type <type 'unicode'>
Length: 14
Characters: Γ ε ι ά σ ο υ κ ό σ μ ε
String of type <type 'str'>
Length: 26
Characters: � � � � � � � � � � � � � � � � � � � � � � � �
使用str
错误地报告了它的长度为26
个字符,并且遍历了返回的字符。另一方面,unicode
正常工作。
堆栈中有nice answer的内容,说明为什么不应该使用它:)