2017-05-11 14 views
3

次の2つのデコード方法が異なる結果を返すのはなぜですか?codecs.iterdecode()が空の文字列を取得するのはなぜですか?

>>> import codecs 
>>> 
>>> data = ['', '', 'a', ''] 
>>> list(codecs.iterdecode(data, 'utf-8')) 
[u'a'] 
>>> [codecs.decode(i, 'utf-8') for i in data] 
[u'', u'', u'a', u''] 

これはバグですか?私のPythonバージョン2.7.13。

+1

デコーダが値を返すかどうかをチェックしているようですが、空の文字列も破棄されます:https://hg.python.org/cpython/file/tip/Lib/codecs.py#l1040 –

答えて

4

これは正常です。 は、エンコードされたチャンクでイテレータを実行し、デコードされたチャンクでイテレータを返しますが、1対1対応を約束しません。すべての出力チャンクの連結は、すべての入力チャンクの連結の有効なデコードであることが保証されています。

あなたはsource codeを見れば、あなたはそれが明示的に空の出力チャンクを破棄しています表示されます:

def iterdecode(iterator, encoding, errors='strict', **kwargs): 
    """ 
    Decoding iterator. 
    Decodes the input strings from the iterator using an IncrementalDecoder. 
    errors and kwargs are passed through to the IncrementalDecoder 
    constructor. 
    """ 
    decoder = getincrementaldecoder(encoding)(errors, **kwargs) 
    for input in iterator: 
     output = decoder.decode(input) 
     if output: 
      yield output 
    output = decoder.decode("", True) 
    if output: 
     yield output 

が理由iterdecodeが存在することに注意してください、そしてあなただけのdecodeを呼び出すことはありません理由すべてのチャンクで、デコード処理がステートフルであることです。 1文字のUTF-8でエンコードされた形式は、複数のチャンクに分割される可能性があります。他のコーデックでは、バイトシーケンスを再び見るまで、すべての文字の大文字と小文字を逆転させるバイトシーケンスのような、本当に奇妙なステートフルな動作をするかもしれません。

関連する問題