web-dev-qa-db-ja.com

Python 3で文字列をバイトに変換する最良の方法は?

TypeErrorに対する回答に見られるように、文字列をバイトに変換する2つの異なる方法があるようです: 'str'はバッファインタフェースをサポートしません

これらの方法のうちどれがPythonicより優れているでしょうか、それとももっと優れていますか?それとも単に個人的な好みの問題ですか?

b = bytes(mystring, 'utf-8')

b = mystring.encode('utf-8')
591
Mark Ransom

bytesのドキュメントを見ると、それは bytearray を指しています。

bytearray([source [、encoding [、errors]]])

新しいバイト配列を返します。 bytearray型は、0 <= x <256の範囲の整数の可変シーケンスです。これには、可変シーケンス型で説明されている、可変シーケンスの通常のメソッドのほとんどがあります。バイト配列メソッド.

オプションのsourceパラメータを使用して、いくつかの異なる方法で配列を初期化できます。

文字列の場合は、エンコーディング(およびオプションでエラー)のパラメータも指定する必要があります。次にbytearray()は、str.encode()を使用して文字列をバイトに変換します。

整数の場合、配列はそのサイズを持ち、nullバイトで初期化されます。

バッファインタフェースに準拠したオブジェクトの場合、そのオブジェクトの読み取り専用バッファがbytes配列の初期化に使用されます。

反復可能な場合は、配列の初期値として使用される0 <= x <256の範囲の整数の反復可能でなければなりません。

引数なしで、サイズ0の配列が作成されます。

それでbytesは単に文字列をエンコードする以上のことができます。 Pythonicでは、意味のある任意のタイプのソースパラメータを使用してコンストラクタを呼び出すことができます。

文字列をエンコードする場合、some_string.encode(encoding)はコンストラクタを使用するよりもPythonicであると思います。なぜなら、それは最も自明な文書化である - 「この文字列をこのエンコードでエンコードする」のほうがbytes(some_string, encoding)より明確だからです。コンストラクタを使用してください。

編集: 私はPythonのソースをチェックしました。 CPythonを使用してUnicode文字列をbytesに渡すと、 PyUnicode_AsEncodedString が呼び出されます。これはencodeの実装です。そのため、自分でencodeを呼び出しても、間接的なレベルをスキップするだけです。

また、Serdalisのコメントを参照してください - unicode_string.encode(encoding)は、その逆がbyte_string.decode(encoding)で対称性がNiceであるため、よりPythonicです。

447
agf

思ったより簡単です。

my_str = "hello world"
my_str_as_bytes = str.encode(my_str)
type(my_str_as_bytes) # ensure it is byte representation
my_decoded_str = my_str_as_bytes.decode()
type(my_decoded_str) # ensure it is string representation
215
hasanatkazmi

absolutely最良の方法は、2つではなく、3番目です。 encodeの最初のパラメーターは、Python 3.0以降はデフォルトで'utf-8'になります。したがって、最善の方法は

b = mystring.encode()

デフォルトの引数はCコードの文字列"utf-8"ではなく、NULLであるmuchであるため、これも高速になります。 チェックが速くなりました!

ここにいくつかのタイミングがあります:

In [1]: %timeit -r 10 'abc'.encode('utf-8')
The slowest run took 38.07 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 183 ns per loop

In [2]: %timeit -r 10 'abc'.encode()
The slowest run took 27.34 times longer than the fastest. 
This could mean that an intermediate result is being cached.
10000000 loops, best of 10: 137 ns per loop

警告にもかかわらず、時間は繰り返し実行後に非常に安定していました-偏差はわずか約2%でした。


引数なしでencode()を使用すると、Python 2と互換性がなくなります。たとえば、Python 2の場合、デフォルトの文字エンコーディングはASCII

>>> 'äöä'.encode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
95
Antti Haapala

あなたは単純に文字列をバイトに変換することができます:

a_string.encode()

そして、あなたは単純にバイトを文字列に変換することができます:

some_bytes.decode()

bytes.decodestr.encodeはデフォルト値としてencoding='utf-8'を持っています。

以下の関数( 有効なPython から取得)は、strbytesに、bytesstrに変換するのに役立ちます。

def to_bytes(bytes_or_str):
    if isinstance(bytes_or_str, str):
        value = bytes_or_str.encode() # uses 'utf-8' for encoding
    else:
        value = bytes_or_str
    return value # Instance of bytes


def to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes):
        value = bytes_or_str.decode() # uses 'utf-8' for encoding
    else:
        value = bytes_or_str
    return value # Instance of str
36
lmiguelvargasf
so_string = 'stackoverflow'
so_bytes = so_string.encode( )
9
gerardw