В чем отличие между "# - * - coding: utf-8 - * -" , "из __future__ import unicode_literals" и "sys.setdefaultencoding (" utf8 ")" - PullRequest
0 голосов
/ 29 мая 2018

Что я знаю:

  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, затем япосетил указанные страницы

    UnicodeEncodeError в / admin / blog / vulpaper / 29 / change /
    кодек «ascii» не может кодировать символы в позиции 6-13: порядковый номер не в диапазоне (128)
    .... больше информации об ошибках
    Строка, которую не удалось закодировать / декодировать, была: emcms 外贸 网站 管理 系统

    , для этой проблемы я напишу sys.setdefaultencoding('utf8')в файле настроек Django, чтобы решить это.

Но на самом деле, я не знаю технических подробностей вышеупомянутого.

Что меня смущает:
1. Так как я установил кодировку исходного файла python, почему я должен установить кодировку строки, чтобы моя кодировка была моей любимой кодировкой?
В чем разница между "кодировкой файла" и "кодировкой строки"?
2. Так как я установил «кодировку файла» и «кодировку строки», почему UnicodeEncodeError все еще происходит?

1 Ответ

0 голосов
/ 14 августа 2018

Обычно вам нужно использовать и file encoding, и literal strings encoding, но на самом деле они управляют чем-то совсем другим , и полезно знать разницу.

Кодировка файла

Если вы планируете писать символы юникода в вашем исходном коде в любом месте, например в комментариях или в буквальных строках, вам необходимо изменить кодировку, чтобы синтаксический анализатор Python работал.Установка неправильной кодировки приведет к исключению SyntaxError. PEP 263 подробно объясняет проблему и как вы можете управлять кодировкой синтаксического анализатора.

В Python 2.1 литералы Unicode могут быть записаны только с использованием кодировки на основе Latin-1 "unicode-escape".Это делает среду программирования довольно недружественной для пользователей Python, которые живут и работают в странах, не входящих в Latin-1, таких как многие азиатские страны.

...

Python по умолчанию будет ASCII какстандартное кодирование, если не даны другие подсказки по кодированию.

Литеральные строки Unicode

Python 2 использует два различных типа для строк: unicode и str.Когда вы определяете литеральную строку, интерпретатор фактически создает новый объект типа str, который содержит этот литерал.

s = "A literal string"
print type(s)

<type 'str'>

TL; DR

Если вы хотите изменить этоПоведение и вместо этого создайте unicode объект каждый раз, когда определен строковый литерал без префикса, вы можете использовать from __future__ import unicode_literals

Если вам нужно понять, почему это полезно, продолжайте читать.

Вы можете явно определить буквальную строку как юникод, используя префикс u.Вместо этого интерпретатор создаст объект 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 работал как ожидалось.

Установка sys.setdefaultencoding ('utf8')

В переполнении стека есть хороший ответ о том, почему мы не должныне используйте его:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...