【问题标题】:tags with unicode in names, and lxml名称中带有 unicode 的标签和 lxml
【发布时间】:2012-04-22 22:04:27
【问题描述】:

假设我有一个在标签名称中使用 Unicode 的文档,例如 <año>2012</año>

当我使用 lxml 中的 etree 来解析这样的文档时,我没有问题,树是正确构建的。但是当(出于调试目的)我尝试打印一些元素时,我得到一个关于尝试将一些 unicode char 编码为 ASCII 失败的异常。

不是终端配置或文件编码错误的问题,因为我可以毫无问题地打印包含相同 unicode 字符的节点名称 (.tag)。显然问题是由 Element 对象的“字符串化”引起的,它假定标签名称是纯 ascii。

下面的代码说明了问题(也说明不是文件/终端/编码问题)。

# coding: utf-8
from lxml import etree
doc = """<?xml version="1.0" encoding="utf-8"?>
<año>2012</año>
"""
x = etree.fromstring(doc)   # No problem
print x.tag                 # No problem
print x                     # Exception

在具有正确定义的 LC_CTYPE 的终端中运行上述脚本,会产生以下输出:

año
Traceback (most recent call last):
  File "procesar.py", line 8, in <module>
    print x
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 10: ordinal not in range(128)

注意print x.tag 如何正确输出añoprint x 不应该产生类似&lt;Element año at b7d26eb4&gt; 的东西吗?

这是一个已知问题吗?有关解决方法的任何想法?

【问题讨论】:

  • 我可以用 lxml 重现这个。 ElementTree 有效;它打印&lt;Element u'a\xf1o' at 0xbf5530&gt;
  • 我尝试使用 ElementTree 并且有同样的异常。也许我使用的是旧版本并且问题已解决。 help(elementtree) 在我的机器上显示# $Id: __init__.py 1821 2004-06-03 16:57:49Z fredrik $,它看起来已经够老了......顺便说一句,当你说“我可以重现这个......”时,你的意思是你有同样的问题,还是有错字?跨度>
  • 无论如何......这是一个有点不同的问题。如何重新定义 Element.__repr__ 以便尝试解决问题?如果我尝试做x.__repr__ = other_function 我得到AttributeError: 'etree._Element' object attribute '__repr__' is read-only

标签: python unicode lxml


【解决方案1】:

你必须在输出之前将 unicode 字符串转换为字节字符串

试试:

print unicode(x).encode('utf8')

引用unicode function

对于提供 __unicode__() 方法的对象,它将不带参数调用此方法来创建 Unicode 字符串。对于所有其他对象,请求 8 位字符串版本或表示,然后使用“严格”模式下的默认编码的编解码器将其转换为 Unicode 字符串。

【讨论】:

  • 其实不需要最后的encode步骤,因为python会自动尝试将unicode字符串编码为终端编码。就我而言,因为我定义了LC_ALL,所以print unicode(x) 有效。但是,我不明白为什么。我认为 unicode(x) 首先尝试 x.__str__ 或 x.__repr__ 应该引发相同的异常,不是吗?
  • @JLDiaz Python 首先尝试使用__unicode__ 方法,如果它不存在,则尝试转换。在答案中添加了关于此的引用。
  • @Marcin 不,他正在使用像字符串这样的对象,你不能简单地“打印”一个对象,这没有意义,它必须被转换,这就是 unicode 函数所做的,将其转换为 unicode 字符串。
  • @KurzedMetal 但是, print x.__unicode__() 不起作用,因为 Element 对象不提供 __unicode__() 方法。那么……它是如何工作的呢?
  • @KurzedMetal 你的代码是正确的,但你的解释充其量是误导。
猜你喜欢
  • 2011-07-05
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 2011-02-20
相关资源
最近更新 更多