Почему объявляют unicode строкой в Python?

Я все еще изучаю Python, и у меня есть сомнение:

В Python 2.6.x я обычно объявляю кодирование в заголовке файла как это (как в PEP 0263)

# -*- coding: utf-8 -*-

После этого мои строки записаны, как обычно:

a = "A normal string without declared Unicode"

Но каждый раз я вижу код проекта Python, кодирование не объявляется в заголовке. Вместо этого это объявляется в каждой строке как это:

a = u"A string with declared Unicode"

Какая разница? Какова цель этого? Я знаю, что Python 2.6.x устанавливает ASCII, кодирующий по умолчанию, но он может быть переопределен объявлением заголовка, таким образом, какой смысл на строковое объявление?

Приложение: Кажется, что я перепутал кодирование файла строковым кодированием. Спасибо за объяснение его :)

120
задан Oscar Carballal 3 July 2010 в 04:39
поделиться

4 ответа

Это две разные вещи, как отмечали другие.

Когда вы указываете # - * - coding: utf-8 - * - , вы сообщаете Python, что исходный файл, который вы сохранили, - utf-8 . По умолчанию для Python 2 используется ASCII (для Python 3 это utf-8 ). Это просто влияет на то, как интерпретатор читает символы в файле.

В целом, вероятно, не лучшая идея встраивать в файл высокие символы Юникода независимо от кодировки; вы можете использовать строковые escape-последовательности Unicode, которые работают в любой кодировке.


Когда вы объявляете строку с u впереди , например u'This is a string ', она сообщает компилятору Python, что это строка Unicode, а не байтов. Интерпретатор обрабатывает это в основном прозрачно; наиболее очевидное отличие состоит в том, что теперь вы можете вставлять символы Юникода в строку (то есть u '\ u2665' теперь разрешено). Вы можете использовать из __future__ import unicode_literals , чтобы сделать его значением по умолчанию.

Это применимо только к Python 2; в Python 3 по умолчанию используется Unicode, и вам нужно указать b впереди (например, b 'Это байты' , чтобы объявить последовательность байтов).

164
ответ дан 24 November 2019 в 01:40
поделиться

Это не устанавливает формат строки; он устанавливает формат файла. Даже с этим заголовком «hello» является байтовой строкой, а не строкой Unicode. Чтобы сделать его Unicode, вам придется везде использовать u "hello" . Заголовок - это всего лишь намек на то, какой формат использовать при чтении файла .py .

10
ответ дан 24 November 2019 в 01:40
поделиться

Определение заголовка должно определять кодировку самого кода, а не результирующих строк во время выполнения.

размещение символа, отличного от ascii, например ۲, в скрипте python без определения заголовка utf-8 вызовет предупреждение

error

7
ответ дан 24 November 2019 в 01:40
поделиться

Как уже говорили другие, # coding: указывает кодировку, в которой сохраняется исходный файл. Вот несколько примеров, иллюстрирующих это:

Файл, сохраненный на диске как cp437 (моя консольная кодировка), но без объявленной кодировки

b = 'über'
u = u'über'
print b,repr(b)
print u,repr(u)

Выход:

  File "C:\ex.py", line 1
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

Выход файла с # coding: cp437 добавлен:

über '\x81ber'
über u'\xfcber'

Сначала Python не знал кодировки и жаловался на то, что символ не является символом ASCII. Как только он узнал кодировку, байтовая строка получила байты, которые действительно были на диске. Для строки Unicode Python прочитал \x81, узнал, что в cp437 это ü, и декодировал его в кодовую точку Unicode для ü - U+00FC. При печати байтовой строки Python отправлял шестнадцатеричное значение 81 непосредственно на консоль. Когда печаталась строка Unicode, Python правильно определил кодировку моей консоли как cp437 и перевел Unicode ü в значение cp437 для ü.

Вот что происходит с файлом, объявленным и сохраненным в UTF-8:

├╝ber '\xc3\xbcber'
über u'\xfcber'

В UTF-8 ü кодируется как шестнадцатеричные байты C3 BC, поэтому байтовая строка содержит эти байты, но строка Unicode идентична первому примеру. Python прочитал два байта и правильно их декодировал. Python напечатал строку байтов неправильно, потому что он отправил два байта UTF-8, представляющие ü, прямо в консоль cp437.

Здесь файл объявлен как cp437, но сохранен в UTF-8:

├╝ber '\xc3\xbcber'
├╝ber u'\u251c\u255dber'

Строка байтов все равно получила байты на диске (UTF-8 hex байты C3 BC), но интерпретировала их как два символа cp437 вместо одного символа, закодированного в UTF-8. Эти два символа были переведены в кодовые точки Unicode, и все печатается неправильно.

23
ответ дан 24 November 2019 в 01:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: