0

私はpython 3.2で作業していますが、エスケープされた文字を処理する方法はほとんど...非決定的です。それらを実際に(エスケープではなく)改行として機能させる唯一の方法は、それらを印刷することです。動作は次のようになります。

>>> a = 'a\nb'
>>> a
'a\nb'
>>> a.encode('ascii')
b'a\nb'
>>> print(a)
a
b
>>> print(a.encode('ascii'))
b'a\nb'
>>> print(str(a.encode('ascii')))
b'a\nb'

これの複雑さはどこかに文書化されていると確信していますが、それを見つけることができません。エンコード (デコード?) の反対のバイト -> 文字列メソッドがどこかにあるかもしれません。

4

1 に答える 1

5

それは完全に決定論的で単純です。ただし、バイトとユニコード文字列の違いに注意する必要があります。Ned Batchelder のPragmatic Unicodeを読んでください。

aは 3 文字で構成された Unicode 文字列を参照するため、それをa評価し、Python REPL はそれを試みます。最初のステップは、それを(文字列用の)print()に変換することです。結果の文字列は、stdout (端末など) に関連付けられたエンコーディングに従ってバイトに変換され、これらのバイトがそこに送信されます。端末は、使用するエンコーディングに従って、受信したバイトを解釈します。strreturn self

a.encode('ascii')ASCII エンコーディングを使用して、Unicode を明示的にバイト シーケンスに変換します。その結果はバイト オブジェクトであり、その結果はprintPython REPL によって 'd されます。繰り返しますが、最初のステップはそれを文字列に変換することです。バイトは文字列ではなく、Python 2 のエンコード/デコード エラーが証明するように、2 つの間の暗黙的な変換は非常に有害であるため、次のような結果しか得reprられません。同等の文字列Python ソース コードのバイト リテラルに。この文字列は、以前と同じように出力されますが、違いは同じです。

では、上記と同じ結果で自分自身を>>> print(a)呼び出します。結果はisなので、Python REPL はそれを出力しません。とについても同じです。暗黙的にではなく、明示的に印刷をトリガーし、事前に変換を行うだけです。printprintNone>>> print(a.encode('ascii'))>>> print(str(a.encode('ascii')))str

確かに の逆がありstr.encode、実際に呼び出され、オブジェクトdecodeのメソッドです。bytesそのsome_str.encode(E).decode(E)ため、ノーオペレーションになる可能性があります。また、途中で情報を失ったり、文字列を変更したり (未知の文字を置き換えるなど) したり、情報を失うように要求しないと例外をスローしたりすることもあります。

何らかのエンコーディングで何らかの文字列を表すバイトがある場合、それらを I/O に使用できます。実際、これは I/O を行う「ネイティブ」な方法です。すべての I/O とすべてのネットワークはバイトです。しかしprint、文字列用です。代わりに、ファイル I/O (stdout を含む) の場合は、それらをバイナリ モードで開き、.writeメソッドを使用します。具体的にはsys.stdout、デフォルトではテキスト モードが使用されますが、バイナリ バージョンにはsys.stdout.buffer. もちろん、送信するバイトが異なるエンコーディングを想定して作成された場合 (またはテキストとしてまったく意図されていない場合) は、意味不明になります。

于 2012-08-25T22:29:59.363 に答える