2014-03-12 38 views
4

Inline::Python ::對象重載'""'(字符串化)與此:字符串化內聯::的Python:對象編碼的Unicode字符串

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->encode('utf8')更換$self->__str__()。我不太喜歡像這樣修改模塊,並且對它進行子類化似乎是一個相當大的挑戰。而且,我不能100%確定我的修復程序爲什麼能夠正常工作,這有點令人擔憂。

我很確定我不是第一個需要在Perl中使用Python Unicode字符串的人。這應該怎麼做?

+2

**正常**的行爲將爲您的Python代碼顯式編碼;不要使用'str(unicodevalue)',其中可以使用unicodevalue.encode('utf8')'。 –

+0

這將是有道理的,但不幸的是,「我的」Python代碼並非真的是我的,我正在使用Inline :: Python將HTTP4Store Python庫加載到Perl中。不得不修改一個Python庫會像修改'Inline :: Python'一樣惱人,因爲我不擅長Python,所以風險更大。 :-( – scozy

+0

我承認不知道Perl會爲*調用'__inline_str__'子*;如果Python源代碼被解碼爲Unicode,然後解析,那麼這就是錯誤的地方,因爲Python中的字節字符串文字保存原始的未編碼字節(所以值爲0-255)。你知道Perl首先用於解碼源代碼的編解碼器嗎? –

回答

-1

One workaround that seems to be working, is replacing $self->str() with $self->encode('utf8').

這是處理這個問題的正確方法。該代碼將編碼任何UTF字符是這樣的:

>>> u'\ufdef'.__str__() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufdef' in position 0: ordinal not in range(128) 
>>> u'\ufdef'.encode('utf-8') 
'\xef\xb7\xaf' 

然後,您將可能需要使用UTF-8解碼器在你的PERL正確顯示值。

+1

注意:'1 .__ str __()'工作,但'1 .encode('utf-8')'失敗 – jfs

+0

如果你能證明'py_has_attr($ self,'__str __')'將永遠不會爲沒有「編碼」方法的對象返回真實值。即使在這種情況下,它並沒有真正回答我關於如何使用Inline :: Python的問題,而不是如何改變它。 – scozy