【发布时间】:2014-04-16 15:10:46
【问题描述】:
Inline::Python::Object 重载'""'(字符串化):
sub __inline_str__ {
my ($self) = @_;
return Inline::Python::py_has_attr($self, '__str__') ? $self->__str__() : $self;
}
__str__() 方法尝试转换为 ASCII,这意味着如果 Inline::Python::Object 对象表示 Python Unicode 字符串,可能的结果是:
exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 6: ordinal not in range(128) at line 1252
似乎有效的一种解决方法是将$self->__str__() 替换为$self->encode('utf8')。我不太喜欢像这样修改模块,并且子类化它似乎是一个相当大的挑战。此外,我不能 100% 确定为什么我的修复程序会起作用,这有点令人担忧。
我很确定我不是第一个需要在 Perl 中使用 Python Unicode 字符串的人。这应该怎么做?
【问题讨论】:
-
正常行为是让您的 Python 代码显式编码;不要使用
str(unicodevalue),在可以使用unicodevalue.encode('utf8')的地方。 -
这是有道理的,但不幸的是,“我的”Python 代码并不是真正属于我的,我使用
Inline::Python将 HTTP4Store Python 库加载到 Perl 中。必须修改 Python 库与必须修改Inline::Python一样令人恼火,因为我对 Python 并不精通,所以风险更大。 :-( -
我承认不知道 Perl 会调用什么
__inline_str__sub for;如果 Python 源代码被解码为 Unicode,然后被解析,那么这就是出错的地方,因为 Python 中的字节字符串文字包含普通的未编码字节(因此值为 0-255)。你知道 Perl 最初使用什么编解码器来解码源代码吗? -
我不认为除了我的 Perl 源代码中包含的内容(即
from HTTP4Store import HTTP4Store as HTTP4Store_Python)之外,Perl 实际上还涉及 Python 源代码。不过老实说,我真的不确定Inline::Python是如何工作的,而且我在 XS 方面也不够好,无法从源头上分辨出来...... -
如果在任何 Python 对象上调用此函数,则不能使用
.encode()(它不是为任意对象定义的)。如果字符串表示用于调试,那么您可以调用repr(self)(通过py_call_function)而不是self.__str__()。