2016-01-31 3 views
1

Использование python 3.5. Из моего понимания все строки должны быть unicode по умолчанию. Почему эти имена ключей Unicode кодируются с помощью ascii?Unicode Dict Keys Issue

row_map = { 
      'α-Pinene': 7, 
      'β-Pinene': 8, 
      'Terpinolene': 9, 
      'Geraniol': 10, 
      'α-Terpinene': 11, 
      'γ-Terpinene': 12, 
      'Camphene': 13, 
      'Linalool': 14, 
      'd-Limonene': 15, 
      'Citral': 16, 
      'Myrcene': 17, 
      'α-Terpineol': 18, 
      'Citronellol': 19, 
      'dl-Menthol': 20, 
      '1-Borneol': 21, 
      '2-Piperidone': 22, 
      'β-Caryophyllene': 23, 
      'α-Humulene': 24, 
      'Caryophyllene Oxide': 5, 
     } 
     with open("log.txt", "w", encoding="utf-8") as f: 
      print(row_map, file=f) 
     print(open("log.txt", "rb").read()) 

Вот результаты написания этих ключей к utf-8. log.txt

dict_keys([ 
    'Terpinolene', 
    'Camphene', 
    'Myrcene', 
    'α-Terpineol', 
    'd-Limonene', 
    '2-Piperidone', 
    'γ-Terpinene', 
    'Geraniol', 
    'Linalool', 
    'α-Humulene', 
    'α-Pinene', 
    'β-Caryophyllene', 
    'β-Pinene', 
    'Caryophyllene Oxide', 
    'Citronellol', 
    '1-Borneol', 
    'Citral', 
    'α-Terpinene', 
    'dl-Menthol']) 

EDIT:Here фактический текстовый файл. Поэтому можно проверить, что это не мой зритель.

EDIT # 2: Пожалуйста, взгляните на эту забаву.

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 bit (AMD64)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> row_map = { 
...     'α-Pinene': 7, 
...     'β-Pinene': 8, 
...     'Terpinolene': 9, 
...     'Geraniol': 10, 
...     'α-Terpinene': 11, 
...     'γ-Terpinene': 12, 
...     'Camphene': 13, 
...     'Linalool': 14, 
...     'd-Limonene': 15, 
...     'Citral': 16, 
...     'Myrcene': 17, 
...     'α-Terpineol': 18, 
...     'Citronellol': 19, 
...     'dl-Menthol': 20, 
...     '1-Borneol': 21, 
...     '2-Piperidone': 22, 
...     'β-Caryophyllene': 23, 
...     'α-Humulene': 24, 
...     'Caryophyllene Oxide': 25, 
...    } 
>>> row_map 
{'Citral': 16, 'd-Limonene': 15, 'Myrcene': 17, 'Camphene': 13, 'ß-Caryophyllene': 23, 'α-Terpinene': 11, 'Linalool': 14, 'α-Humulene': 24, '1-Borneol': 21, 'Citronellol': 19, 'Caryophyllene Oxide': 25, 'α-Terpineol': 18, 'α-Pinene': 7, '2-Piperidone': 22, 'dl-Menthol': 20, 'Terpinolene': 9, 'ß-Pinene': 8, 'Geraniol': 10, '?-Terpinene': 12} 
>>> from strains.models import Terpene 
>>> Terpene.row_map 
{'Citral': 16, 'd-Limonene': 15, 'Myrcene': 17, 'Camphene': 13, 'α-Terpinene': 11, 'Linalool': 14, 'α-Humulene': 24, '1-Borneol': 21, 'Citronellol': 19, 'Caryophyllene Oxide': 25, 'α-Terpineol': 18, 'α-Pinene': 7, '\u03b2-Caryophyllene': 23, '2-Piperidone': 22, 'dl-Menthol': 20, 'Terpinolene': 9, '\u03b3-Terpinene': 12, 'Geraniol': 10, '\u03b2-Pinene': 8} 
>>> 

Я скопировал это из кода проблемы и вставил его в оболочку. Обратите внимание, как вставленный dict автоматически заменил все, что он не мог кодировать с помощью ?.

Обратите внимание, что тот же самый точный dict, который является атрибутом Terpene obj, ускользнул от юникода!

Вот терпене объекта row_map

class Terpene(models.Model): 

    name = models.CharField(max_length=50, unique=True) 
    short_desc = models.CharField(max_length=250, blank=True, null=True) 
    long_desc = models.TextField(blank=True, null=True) 
    aroma = models.CharField(max_length=250, blank=True, null=True) 
    flavor = models.CharField(max_length=250, blank=True, null=True) 
    effects = models.CharField(max_length=250, blank=True, null=True) 

row_map = { 
    'α-Pinene': 7, 
    'β-Pinene': 8, 
    'Terpinolene': 9, 
    'Geraniol': 10, 
    'α-Terpinene': 11, 
    'γ-Terpinene': 12, 
    'Camphene': 13, 
    'Linalool': 14, 
    'd-Limonene': 15, 
    'Citral': 16, 
    'Myrcene': 17, 
    'α-Terpineol': 18, 
    'Citronellol': 19, 
    'dl-Menthol': 20, 
    '1-Borneol': 21, 
    '2-Piperidone': 22, 
    'β-Caryophyllene': 23, 
    'α-Humulene': 24, 
    'Caryophyllene Oxide': 25, 
} 

EDIT 3:

Вот бинарное чтение из проблемного кода:

b"{'\xc3\x8e\xc2\xb1-Terpinene': 11, 'Geraniol': 10, '\xc3\x8e\xc2\xb1-Pinene': 7, 'dl-Menthol': 20, 'Myrcene': 17, 'Citral': 16, 'Citronellol': 19, 'Camphene': 13, '\xc3\x8e\xc2\xb3-Terpinene': 12, '\xc3\x8e\xc2\xb1-Terpineol': 18, '1-Borneol': 21, '\xc3\x8e\xc2\xb1-Humulene': 24, '\xc3\x8e\xc2\xb2-Caryophyllene': 23, '\xc3\x8e\xc2\xb2-Pinene': 8, '2-Piperidone': 22, 'Caryophyllene Oxide': 25, 'Linalool': 14, 'Terpinolene': 9, 'd-Limonene': 15}\r\n" 

Здесь бинарное чтение из Terpene Object row_map:

b"{'Geraniol': 10, '\xce\xb2-Caryophyllene': 23, '\xce\xb1-Pinene': 7, 'Citral': 16, '\xce\xb3-Terpinene': 12, 'Myrcene': 17, 'Camphene': 13, '\xce\xb1-Terpinene': 11, 'dl-Menthol': 20, '1-Borneol': 21, '\xce\xb1-Humulene': 24, '\xce\xb2-Pinene': 8, 'd-Limonene': 15, 'Citronellol': 19, '2-Piperidone': 22, 'Caryophyllene Oxide': 25, '\xce\xb1-Terpineol': 18, 'Linalool': 14, 'Terpinolene': 9}\r\n" 
+1

Поскольку вы просматриваете файл с помощью программы просмотра, которая не понимает utf-8? –

+0

Я использую Sublime Text 3 с '" default_encoding ":" UTF-8 "'. 'view.encoding()' раскрывает 'UTF-8' –

+2

Вместо того, чтобы давать ссылку на внешний файл (который мог пройти через неожиданную перекодировку), вы можете просто добавить' print (open ("log.txt" , "rb"). read()) 'сразу после блока' with' и покажите нам результаты. Это поможет нам найти ошибку кодирования, которая звучит так, как будто она находится на вашем терминальном уровне. – DSM

ответ

1

«Почему эти имена ключей Unicode кодируются в ascii?»

Это не так. «Закодированные в формате ASCII» даже не имеет смысла, и кодирующие их с помощью ASCII даже не работает:

>>> 'α-Terpineol'.encode('ascii') 
Traceback (most recent call last): 
    File "<pyshell#17>", line 1, in <module> 
    'α-Terpineol'.encode('ascii') 
UnicodeEncodeError: 'ascii' codec can't encode character '\u03b1' in position 0: ordinal not in range(128) 

Похоже, после правильного кодирования с использованием UTF-8, ваш просмотрщик файлов декодируется с помощью ISO-8859-1 или около того:

>>> 'α-Terpineol'.encode('utf-8').decode('ISO-8859-1') 
'α-Terpineol' 
+0

Я понимаю, откуда вы. Пожалуйста, см. Ссылку для ссылки на фактический файл txt, чтобы проверить кодировку и содержимое. Благодарю. –

+0

Права на Google Диск установлены неправильно. Теперь любой, у кого есть ссылка, должен быть в состоянии просмотреть. С уважением. –