“# - * - coding:utf-8 - * - ”,“from __future__ import unicode_literals”和“sys.setdefaultencoding(”utf8“)”之间的区别是什么?

时间:2018-05-29 08:19:56

标签: python django encoding utf-8

我所知道的是:

  1. # -*- coding: utf-8 -*-
    它用于声明Python源文件的编码,一旦我设置了编码名称,Python解析器将使用给定的编码解释文件。我称之为“文件编码”;

  2. from __future__ import unicode_literals 我正在使用Python2.7完成任务,并使用from __future__ import unicode_literals将字符串的默认类型从“str”更改为“unicode”。我称之为“字符串编码”;

  3. sys.setdefaultencoding('utf8') 但有时,我在Django中出现错误,例如,我在管理员中存储了中文,然后我访问了相关的页面

      

    / admin / blog / vulpaper / 29 / change /
    的UnicodeEncodeError   'ascii'编解码器无法编码位置6-13中的字符:序数不在范围(128)中   ....错误信息越多   无法编码/解码的字符串是:emcms外贸网站管理系统

    对于这个问题,我将在Django设置文件中编写sys.setdefaultencoding('utf8')来解决它。

  4. 但实际上,我不知道上述技术细节。

    令我困惑的是:
    1.由于我设置了python源文件编码,为什么要设置字符串编码以确保我的字符串编码是我最喜欢的编码?
    “文件编码”和“字符串编码”有什么不同?
    2.由于我设置了“文件编码”和“字符串编码”,为什么还会发生UnicodeEncodeError?

1 个答案:

答案 0 :(得分:2)

通常,您必须同时使用file encodingliteral strings encoding,但它们实际上控制的是非常不同,并且有助于了解它们之间的区别。

文件编码

如果您希望在源代码中的任何地方(例如注释或文字字符串)写入unicode字符,则需要更改编码以使python解析器正常工作。设置错误的编码将导致SyntaxError异常。 PEP 263详细说明了该问题以及如何控制解析器的编码。

  

在Python 2.1中,只能使用Latin-1编写Unicode文字   基于编码的“ unicode-escape”。这使得编程   环境对居住和工作的Python用户而言并不友好   非拉丁1区域设置,例如许多亚洲国家/地区。

     

...

     

如果未提供其他编码提示,Python将默认使用ASCII作为标准编码。

Unicode文字字符串

Python 2对字符串使用两种不同的类型,unicodestr。当您定义文字字符串时,解释器实际上会创建一个保存该文字的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类型使字符级操作正常工作很重要正确地。以下示例显示了对于完全相同的文字,使用strunicode进行字符级解释的区别。

# -*- 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正常工作。

设置sys.setdefaultencoding('utf8')

堆栈中有nice answer的内容,说明为什么不应该使用它:)