python ascii vs unicode (utf-8) [duplicate]

Вы можете использовать декларативный модуль для списков данных, таких как query-js (*). В этих ситуациях я лично считаю декларативный подход менее неожиданным

var funcs = Query.range(0,3).each(function(i){
     return  function() {
        console.log("My value: " + i);
    };
});

. Затем вы можете использовать свой второй цикл и получить ожидаемый результат, или вы могли бы сделать

funcs.iterate(function(f){ f(); });

(*) Я автор запросов-js и поэтому склонен к его использованию, поэтому не принимайте мои слова в качестве рекомендации для указанной библиотеки только для декларативного подхода:)

188
задан Aaron Hall 13 May 2016 в 21:29
поделиться

7 ответов

Исключительно используйте объекты unicode как можно больше, расшифровывая объекты для unicode-объектов, когда вы их сначала получаете и кодируете по мере необходимости.

Если ваша строка на самом деле является объектом unicode, вы нужно будет преобразовать его в строковый объект, закодированный в кодировке unicode, прежде чем записывать его в файл:

foo = u'Δ, Й, ק, ‎ م, ๗, あ, 叶, 葉, and 말.'
f = open('test', 'w')
f.write(foo.encode('utf8'))
f.close()

Когда вы снова прочтете этот файл, вы получите строку с кодировкой в ​​кодировке Юникода, которую вы можете декодировать к объекту unicode:

f = file('test', 'r')
print f.read().decode('utf8')
282
ответ дан quasistoic 26 August 2018 в 21:56
поделиться

Предисловие: будет ли ваш просмотрщик работать?

Убедитесь, что ваш просмотрщик / редактор / терминал (однако вы взаимодействуете с вашим файлом, закодированным в utf-8) можете прочитать файл. Это часто возникает в Windows , например, «Блокнот».

Написание текста в текстовом файле в формате Unicode?

In Python 2, используйте open из модуля io (это то же самое, что встроенный open в Python 3):

import io

Лучшая практика, в общем, использует UTF-8 для

encoding = 'utf-8'

utf-8 - это самая современная и универсально используемая кодировка - она ​​работает во всех веб-браузерах , большинство текстовых редакторов (см. ваши настройки, если у вас есть проблемы) и большинство терминалов / оболочек.

В Windows вы можете попробовать utf-16le, если вы ограничены просмотром вывода в Блокноте (или другом ограниченном viewer).

encoding = 'utf-16le' # sorry, Windows users... :(

И просто откройте его с помощью диспетчера контекстов и напишите символы юникода:

with io.open(filename, 'w', encoding=encoding) as f:
    f.write(unicode_object)

Пример использования многих символов Юникода

Вот пример, который пытается сопоставить все возможные символы шириной до трех бит (4 - макс, но это будет немного далеко) от цифрового r epresentation (в целых числах) к выходу с кодированной печатаемой записью вместе с ее именем (поместите это в файл с именем uni.py):

from __future__ import print_function
import io
from unicodedata import name, category
from curses.ascii import controlnames
from collections import Counter

try: # use these if Python 2
    unicode_chr, range = unichr, xrange
except NameError: # Python 3
    unicode_chr = chr

exclude_categories = set(('Co', 'Cn'))
counts = Counter()
control_names = dict(enumerate(controlnames))
with io.open('unidata', 'w', encoding='utf-8') as f:
    for x in range((2**8)**3): 
        try:
            char = unicode_chr(x)
        except ValueError:
            continue # can't map to unicode, try next x
        cat = category(char)
        counts.update((cat,))
        if cat in exclude_categories:
            continue # get rid of noise & greatly shorten result file
        try:
            uname = name(char)
        except ValueError: # probably control character, don't use actual
            uname = control_names.get(x, '')
            f.write(u'{0:>6x} {1}    {2}\n'.format(x, cat, uname))
        else:
            f.write(u'{0:>6x} {1}  {2}  {3}\n'.format(x, cat, char, uname))
# may as well describe the types we logged.
for cat, count in counts.items():
    print('{0} chars of category, {1}'.format(count, cat))

Это должно выполняться примерно в минуту , и вы можете просмотреть файл данных, и если ваш просмотрщик файлов может отображать unicode, вы увидите его. Информацию о категориях можно найти здесь здесь . Основываясь на подсчетах, мы, вероятно, можем улучшить наши результаты, исключив категории Cn и Co, у которых нет связанных с ними символов.

$ python uni.py

Будет отображено шестнадцатеричное отображение, category , символ (если не удается получить имя, возможно, контрольный символ) и имя символа. например,

Я рекомендую less в Unix или Cygwin (не печатайте / не копируйте весь файл на ваш выход):

$ less unidata

, например. будет отображаться аналогично следующим строкам, которые я выбрал из него, используя Python 2 (unicode 5.2):

     0 Cc NUL
    20 Zs     SPACE
    21 Po  !  EXCLAMATION MARK
    b6 So  ¶  PILCROW SIGN
    d0 Lu  Ð  LATIN CAPITAL LETTER ETH
   e59 Nd  ๙  THAI DIGIT NINE
  2887 So  ⢇  BRAILLE PATTERN DOTS-1238
  bc13 Lo  밓  HANGUL SYLLABLE MIH
  ffeb Sm  →  HALFWIDTH RIGHTWARDS ARROW

My Python 3.5 из Anaconda имеет unicode 8.0, я бы предположил, что большинство 3 будет.

13
ответ дан Aaron Hall 26 August 2018 в 21:56
поделиться

Как печатать символы Unicode в файл:

Сохранить это в файле: foo.py:

#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
import codecs
import sys 
UTF8Writer = codecs.getwriter('utf8')
sys.stdout = UTF8Writer(sys.stdout)
print(u'e with obfuscation: é')

Запустить его и вывести канал в файл:

python foo.py > tmp.txt

Откройте tmp.txt и загляните внутрь, вы увидите следующее:

el@apollo:~$ cat tmp.txt 
e with obfuscation: é

Таким образом, вы сохранили unicode e с отметкой обфускации на нем в файл.

3
ответ дан Eric Leschinski 26 August 2018 в 21:56
поделиться

В Python 2.6+ вы можете использовать io.open() , который по умолчанию ( builtin open() ) на Python 3:

import io

with io.open(filename, 'w', encoding=character_encoding) as file:
    file.write(unicode_text)

Возможно, было бы более удобно, если вам нужно постепенно писать текст (вам не нужно многократно называть unicode_text.encode(character_encoding)). В отличие от модуля codecs модуль io имеет правильную универсальную поддержку новых строк.

49
ответ дан jfs 26 August 2018 в 21:56
поделиться

Обработка строки Unicode стандартизована в Python 3.

  1. Char хранится в Unicode
  2. Вам нужно только открыть файл в utf-8
    out1 = "(嘉南大圳 ㄐㄧㄚ ㄋㄢˊ ㄉㄚˋ ㄗㄨㄣˋ )"
    fobj = open("t1.txt", "w", encoding="utf-8")
    fobj.write(out1)
    fobj.close()
    
8
ответ дан Rob 26 August 2018 в 21:56
поделиться

Эта ошибка возникает при попытке кодировать строку, отличную от юникода: она пытается ее декодировать, предполагая, что она находится в простой ASCII. Есть две возможности:

  1. Вы кодируете его в байтовую строку, но поскольку вы использовали codecs.open, метод write ожидает объект unicode. Поэтому вы кодируете его, и он пытается его снова декодировать. Попробуйте: f.write(all_html).
  2. all_html не является, по сути, объектом unicode. Когда вы делаете .encode(...), он сначала пытается его декодировать.
1
ответ дан Thomas K 26 August 2018 в 21:56
поделиться

Файл, открытый codecs.open, является файлом, который принимает данные unicode, кодирует его в iso-8859-1 и записывает в файл. Однако вы пытаетесь написать не unicode; вы берете unicode и кодируете его в iso-8859-1 самостоятельно . Это то, что делает метод unicode.encode, а результат кодирования строки юникода - это bytestring (тип str.)

Вы должны либо использовать обычный open(), либо самостоятельно закодировать юникод, либо (обычно лучшая идея), используйте codecs.open() и not сами кодировать данные.

18
ответ дан Thomas Wouters 26 August 2018 в 21:56
поделиться
Другие вопросы по тегам:

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