文字列リテラルの前の「b」文字は何をしますか?


831

どうやら、以下は有効な構文です:

my_string = b'The string'

私が知りたいのですが:

  1. この何をないb文字列の前の文字が意味ですか?
  2. 使用するとどのような影響がありますか?
  3. それを使用する適切な状況は何ですか?

私はSOで関連する質問を見つけましたが、その質問はPHPに関するものであり、それは、bコードがPHP <6のバージョンから互換性を持つために必要であったUnicodeとは対照的に、文字列がバイナリであることを示すために使用されていることを示しています、PHP 6への移行時。これはPythonには当てはまらないと思います。

同じ構文で文字を使用して文字列をUnicodeとして指定することについて、Pythonサイトでこのドキュメントを見つけましたu。残念ながら、そのドキュメントのどこにもb文字については触れられていません。

また、単に好奇心から、より多くのシンボルがあるbu、他の事をしますか?

回答:


416

Python 2.xドキュメントを引用するには

Python 2では、「b」または「B」のプレフィックスは無視されます。これは、リテラルがPython 3でバイトリテラルになることを示します(たとえば、コードが2to3で自動的に変換される場合)。「u」または「b」プレフィックスの後に「r」プレフィックスが続く場合があります。

Pythonの3ドキュメントの状態:

バイトリテラルには、常に「b」または「B」が前に付きます。str型ではなくbytes型のインスタンスを生成します。ASCII文字のみを含めることができます。128以上の数値を持つバイトは、エスケープで表す必要があります。


4
そのため、Python <v3ではこの余分な文字は無視されるようです。通常の文字列ではなくab文字列を使用する必要があるv3の場合はどうなりますか?
Jesse Webb

5
@Gweebz-Unicodeエスケープではなく特定のエンコーディングで文字列を実際に入力している場合(例: '\ u32e1'ではなくb '\ xff \ xfe \ xe12')。
11

7
実際、unicode_literalsからインポートした場合__future__、これはこの特定の文字列の動作を「逆転」します(Python 2.xの場合)
Romuald Brunet

34
引用されたドキュメントに関するもう少し平易な言葉の説明は、これをより良い答えにするでしょう。IMHO
Hack-R

2
そうでなければ、すでにそれを理解している人のための答えです。
Rafael Eyng

680

Python 3.xはタイプを明確に区別します。

  • str= '...'リテラル= Unicode文字のシーケンス(Pythonのコンパイル方法に応じて、UTF-16またはUTF-32)
  • bytes= b'...'リテラル=オクテットのシーケンス(0〜255の整数)

JavaまたはC#に精通している場合は、stras Stringbytesasを考えてくださいbyte[]。SQLに精通している場合は、stras NVARCHARbytesas、BINARYorを考えてくださいBLOB。あなたがWindowsレジストリに精通している場合、と考えるstrようにREG_SZbytesのようにREG_BINARY。C(++)に精通している場合は、学習したすべての内容charと文字列を忘れてください。A CHARACTERはBYTEではないためです。その考えは長い間時代遅れです。

strテキストを表現したい場合に使用します。

print('שלום עולם')

bytes構造体のような低レベルのバイナリデータを表現する場合に使用します。

NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0]

あなたはできるエンコードstrするbytesオブジェクト。

>>> '\uFEFF'.encode('UTF-8')
b'\xef\xbb\xbf'

そして、あなたはデコードすることができますbytesstr

>>> b'\xE2\x82\xAC'.decode('UTF-8')
'€'

ただし、2つのタイプを自由に混在させることはできません。

>>> b'\xEF\xBB\xBF' + 'Text with a UTF-8 BOM'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to str

このb'...'表記は、バイト0x01-0x7Fを16進数ではなくASCII文字で指定できるという点でやや混乱しています。

>>> b'A' == b'\x41'
True

しかし私は強調しなければなりません、文字はバイトではありません

>>> 'A' == b'A'
False

Python 2.xの場合

3.0より前のバージョンのPythonでは、テキストデータとバイナリデータのこのような区別がありませんでした。代わりに、以下がありました:

  • unicode= u'...'リテラル= Unicode文字のシーケンス= 3.xstr
  • str= '...'リテラル=交絡したバイト/文字のシーケンス
    • 通常はテキストであり、特定されていないエンコーディングでエンコードされています。
    • しかし、struct.pack出力などのバイナリデータを表すためにも使用されます。

2.xから3.xへの移行を容易にするために、b'...'リテラル構文はPython 2.6にバックポートされ、バイナリ文字列(bytes3.xにある必要がある)をテキスト文字列(str3にある必要がある)から区別できるようになりました。 。バツ)。bプレフィックスは2.xの中で何もしませんが、伝え2to33.xでUnicode文字列に変換していないスクリプトを

つまりb'...'、Pythonのリテラルには、PHPと同じ目的があります。

また、好奇心から、bやuよりも他のことをするシンボルの方が多いですか?

r接頭辞は、(例えば、生の文字列を作成し、r'\t'バックスラッシュ+であるt代わりのタブ)、三重引用符'''...'''または"""..."""複数行の文字列リテラルを許可します。


2
ありがとう!「2.xから3.xへの移行を容易にするために、b '...'リテラル構文がPython 2.6にバックポートされ、バイナリ文字列を区別できるようになりました(これにより、テキスト文字列(3.xではstrである必要があります)からの3.xのバイトです。bプレフィックスは2.xでは何もしませんが、2to3スクリプトにそれを3.xのUnicode文字列に変換しないように指示します。
tommy.carstensen 2013

4
'A' == b'A' --> Falseチェックは本当にそれがオフになります。それ以外は素晴らしいですが、その時点まで、バイト文字列は実際にはテキストで
ワイルドカード2016

12
'שלום עולם' == 'hello world'
イーライ

12
これは、単にドキュメントを引用している、受け入れられた回答よりもはるかに明確です。私にとってのドキュメントは意味がありませんでしたので、ドキュメントにさらにコンテキストを提供するのは素晴らしいことです。ありがとう!
rayryeng 2018

2
b "some string" .decode( 'UTF-8')、それは多くの人が探している行だと思います
Marvin Thobejane

22

bはバイト文字列を示します。

バイトは実際のデータです。文字列は抽象化です。

複数文字の文字列オブジェクトがあり、単一の文字を受け取った場合、それは文字列であり、エンコーディングによっては1バイトを超えるサイズになる場合があります。

バイト文字列で1バイトを取った場合、0〜255の単一の8ビット値を取得し、エンコードのためにそれらの文字が1バイトを超える場合、完全な文字を表さない可能性があります。

TBHバイトを使用する特定の低レベルの理由がない限り、文字列を使用します。


16

サーバー側から応答を送信すると、バイト型の形式で送信されるため、クライアントには次のように表示されます b'Response from server'

b'....'単に以下のコードを取り除くために:

サーバーファイル:

stri="Response from server"    
c.send(stri.encode())

クライアントファイル:

print(s.recv(1024).decode())

その後、印刷されます Response from server


1
それはジェシー・ウェッブが尋ねた質問を説明していません!
チャンドラカンス

エンコードとデコードのメソッドを使用しない場合、Pythonは文字列型ではなくバイト型としてそれを受け取るため、文字列出力には接頭辞としてb ''が付きます。b 'のような出力を取得したくない場合... '以上を使用してください。理解できなかったことは何ですか?
ナニチンサ

実際、これはまさに質問された質問のタイトルに対する答えです。Q:「b'x 'は何をするのですか?」A:「 'x'.encode()を実行します」これは文字通り実行します。質問の残りの部分はこれ以上のことを知りたいと思っていましたが、タイトルは答えられました。
マイケルエリクソン

10

Python 3.x でがないと例外bがスローされる例を次に示しTypeErrorます

>>> f=open("new", "wb")
>>> f.write("Hello Python!")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

b接頭辞を追加すると問題が解決します。


9

それをbytesリテラルに(またはstr2.xに)変換し、2.6以降で有効です。

r接頭辞は、バックスラッシュが「未解釈」されます(無視されていない、との違いはありません問題)。


これは、aixの回答で引用されているドキュメントによれば、間違っているように思えます。bは3以外のPythonバージョンでは無視されます
Jesse Webb

2
それは次のようになりますstr、無視されるということができたので、2.xのいずれかの方法で。モジュールunicode_literalsからインポートする場合、区別は重要__future__です。
Ignacio Vazquez-Abrams

6

他の人が言ったことに加えて、ユニコードの単一の文字は複数のバイトで構成できることに注意してください。

Unicodeが機能する方法は、古いASCII形式(0xxx xxxxのような7ビットコード)を採用し、すべてのバイトが1で始まるマルチバイトシーケンス(1xxx xxxx)を追加して、ASCIIを超える文字を表し、Unicodeが後方になるようにすることです。 -ASCII互換性があります。

>>> len('Öl')  # German word for 'oil' with 2 characters
2
>>> 'Öl'.encode('UTF-8')  # convert str to bytes 
b'\xc3\x96l'
>>> len('Öl'.encode('UTF-8'))  # 3 bytes encode 2 characters !
3

2

JSONを使用して辞書に変換できます

import json
data = b'{"key":"value"}'
print(json.loads(data))

{"キー": "値"}


フラスコ:

これはフラスコの例です。これを端末行で実行します。

import requests
requests.post(url='http://localhost(example)/',json={'key':'value'})

Flask / routes.py内

@app.route('/', methods=['POST'])
def api_script_add():
    print(request.data) # --> b'{"hi":"Hello"}'
    print(json.loads(request.data))
return json.loads(request.data)

{'key': 'value'}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.