【问题标题】:Unicode Dict Keys IssueUnicode 字典键问题
【发布时间】:2016-05-09 04:51:27
【问题描述】:

使用 python 3.5。据我了解,默认情况下所有字符串都应该是 unicode。为什么这些 un​​icode 键名使用 ascii 编码?

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'])

编辑: Here 是实际的 txt 文件。所以可以验证它不是我的观众。

编辑#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}
>>>

我从问题代码中复制了这个并将其粘贴到 shell 中。请注意粘贴的 dict 是如何自动用 ? 替换它无法编码的任何内容。

注意作为 Terpene obj 的属性的完全相同的 dict 是如何转义 unicode 的!

这是萜烯对象的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,
}

编辑 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"

【问题讨论】:

  • 因为您正在使用不理解 utf-8 的查看器查看文件?
  • 我正在使用带有"default_encoding": "UTF-8" 的 Sublime Text 3。 view.encoding() 透露 UTF-8
  • 您可以在with 块之后立即添加print(open("log.txt", "rb").read()),而不是提供指向外部文件的链接(这可能会经历一些意外的重新编码),并向我们展示结果。这将帮助我们找到编码错误,这听起来像是在您的终端级别。
  • 太棒了!请参阅编辑#3。谢谢。
  • 在 EDIT #2 的 shell 演示中,我想你得到了 '?'因为终端窗口无法处理字符并给出 Python '?',所以 Python 甚至永远不会获取原始字符。在 IDLE shell 中试一试。顺便说一句,如果你写了@DSM 之类的东西,他们就会收到通知。

标签: python dictionary unicode python-3.5 python-unicode


【解决方案1】:

“为什么这些 un​​icode 键名被编码为 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'

【讨论】:

  • 我知道你来自哪里。请参阅编辑以获取实际 txt 文件的链接,以验证自己的编码和内容。谢谢。
  • Google 云端硬盘权限设置不正确。现在任何有链接的人都应该能够查看。问候。
猜你喜欢
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多