【问题标题】:Python UTF-8 conversion problemPython UTF-8 转换问题
【发布时间】:2011-05-18 20:36:52
【问题描述】:

在我的数据库中,我存储了一些 UTF-8 字符。例如。 “名称”字段中的“α”

通过 Django ORM,当我读到这个时,我得到了类似的东西

>>> p.name
u'\xce\xb1'
>>> print p.name
α

我希望得到“α”。

经过一番挖掘,我想如果我这样做了

>>> a = 'α'
>>> a
'\xce\xb1'

所以当 Python 试图显示 '\xce\xb1' 时,我得到了 alpha,但是当它试图显示 u'\xce\xb1' 时,它是双重编码?

为什么我首先得到 u'\xce\xb1'?有没有办法让我恢复 '\xce\xb1'?

谢谢。我的 UTF-8 和 unicode 处理知识确实需要一些帮助...

【问题讨论】:

  • 您是否真的将 UTF-8 存储到数据库中?这不太好......
  • 你得到一个包含字节串的 unicode 文字。某处有问题 - 您是否对其进行编码然后将其存储在 unicode 字段中?如果您需要取回这些值,p.name..encode("iso-8859-1").decode("utf-8") 应该这样做,但这并不能真正解决问题。
  • @IgnacioVazquez-Abrams 嗨,如果您有时间回答,当您需要将 utf - 8 编码的 unicode 符号存储到数据库时,您还有哪些其他选择?
  • @KonstantinosChertouras:不要。正确使用数据库的本地国际字符支持。

标签: python django unicode encoding utf-8


【解决方案1】:

尝试将 unicode 签名 u 放在您的字符串之前,例如u'YOUR_ALFA_CHAR' 并修改您的数据库编码,因为 Django 始终支持 UTF-8。

【讨论】:

  • 如果它是 OP 正在谈论的字符串文字听起来很棒,但我认为它是从数据库中来的。
  • 它来自数据库,我没有输入我自己的字符串文字。当我使用 mysql 命令行工具查看数据库时,我看到了 alpha。编码是 utf8,但是当我在 Python 中加载时,我得到的是 u'\xce\xb1',而不是 '\xce\xb1'。
【解决方案2】:

您似乎拥有的是解释为 unicode 代码点的 UTF-8 编码字符串的各个字节。你可以用这种奇怪的形式“解码”你的字符串:

p.name = ''.join(chr(ord(x)) for x in p.name)

或许

p.name = ''.join(chr(ord(x)) for x in p.name).decode('utf8')

将字符串“编码”成这种形式的一种方法是

''.join(unichr(ord(x)) for x in '\xce\xb1')

虽然我感觉你的字符串实际上是由于系统的不同组件在使用的编码上存在分歧而进入这种状态的。

您可能必须修复错误“编码”的来源,而不仅仅是修复数据库中当前的数据。上面的代码可能可以将你的坏数据转换一次,但我建议你不要将此代码插入到你的 Django 应用程序中。

【讨论】:

  • 一个很好很详细的解释。
  • 你能解释一下为什么 chr(ord(x) 会在 x > 255 时起作用,因为 "chr (x) :返回一个字符的字符串,其 ASCII 码是整数 i。..参数必须在 [0..255] 范围内,包括在内;如果 i 超出该范围,将引发 ValueError。"
【解决方案3】:

问题在于 p.name 未正确存储和/或从数据库中读取。

Unicode 小字母是 U+03B1 并且 p.name 应该打印为 u'\x03b1' 或者如果您使用的是支持 Unicode 的终端,实际的字母符号本身可能已经打印在引号中。注意 u'\xce\xb1' 和 u'\xceb1' 之间的区别。前者是两个字符串,后者是一个字符串。我不知道 UTF-8 的“03”字节是如何翻译成“CE”的。

【讨论】:

    【解决方案4】:

    您可以通过 decode 函数将任何字节序列转换为内部 unicode 表示:

    print '\xce\xb1'.decode('utf-8')
    

    这允许您从任何来源导入字节序列,然后将其转换为 Python unicode 字符串。

    参考:http://docs.python.org/library/stdtypes.html#string-methods

    【讨论】:

    • 问题是打印 u'\xce\xb1'.decode('utf-8'),而不是打印 '\xce\xb1'.decode('utf-8')
    【解决方案5】:

    尝试使用p.name.encode('latin-1') 转换编码。这是一个演示:

    >>> print u'\xce\xb1'
    α
    >>> print u'\xce\xb1'.encode('latin-1')
    α
    >>> print '\xce\xb1'
    α
    >>> '\xce\xb1' == u'\xce\xb1'.encode('latin1')
    True
    

    有关详细信息,请参阅str.encodeStandard Encodings

    【讨论】:

    • 我得到 '\xc3\x8e\xc2\xb1',来自 u'\xce\xb1'
    • 嗯——尝试在latin-1 中编码。我希望这行得通! p.encode('utf-8') 可能会打印“α”;它不应该打印您拥有的字符串。字符串编码是一个非常善变的野兽! :o)
    猜你喜欢
    • 2010-09-21
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    相关资源
    最近更新 更多