web-dev-qa-db-ja.com

文字列リテラルの前にある 'b'文字は何をするのでしょうか。

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

my_string = b'The string'

私が知りたいのですが:

  1. 文字列の前にあるこのb文字はどういう意味ですか?
  2. それを使うことの効果は何ですか?
  3. それを使用するための適切な状況は何ですか?

SOでここに 関連する質問 が見つかりましたが、その質問はPHPについてですが、Unicodeではなくbがバイナリであることを示すために使用されています。 PHP 6に移行するときに、コードがPHP <6のバージョンと互換性を持つために必要でした。これはPythonには当てはまりません。

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

また、好奇心からではありませんが、buよりも他のことをするシンボルがありますか。

603
Jesse Webb

Python 2.xのドキュメント

Python 2では、 'b'または 'B'の接頭辞は無視されます。これは、Python 3ではリテラルがバイトリテラルになることを示しています(たとえば、コードが2to3で自動的に変換される場合)。 「u」または「b」の接頭辞の後に「r」の接頭辞を続けることができます。

Python 3ドキュメント

バイトリテラルは常に 'b'または 'B'で始まります。それらはstr型の代わりにbytes型のインスタンスを生成します。それらはASCII文字のみを含むことができます。 128以上の数値を持つバイトは、エスケープで表現する必要があります。

312
NPE

Python 3.x は型を明確に区別します。

  • str = '...' literals =一連のUnicode文字(Pythonのコンパイル方法に応じてUTF-16またはUTF-32)
  • bytes = b'...'リテラル=一連のオクテット(0から255までの整数)

JavaまたはC#に精通している場合は、strStringbytesbyte[]と考えてください。 SQLに精通しているのであれば、strNVARCHARbytesBINARYまたはBLOBと考えてください。 Windowsレジストリに精通している場合は、strREG_SZbytesREG_BINARYと考えてください。 C(++)に慣れているのであれば、charと文字列について学んだことをすべて忘れてください。これは、 A CHARACTER IS NOT A BYTE です。その考えは時代遅れです。

テキストを表現したいときはstrを使います。

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

構造体のような低レベルのバイナリデータを表現したいときは、bytesを使います。

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

encode _ strbytesオブジェクトにすることができます。

>>> '\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では

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

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

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

つまり、Pythonのb'...'リテラルは、PHPの場合と同じ目的を持っています。

また、好奇心からではなく、bやuよりも他のことをするシンボルがありますか。

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

513
dan04

Bはバイト文字列を表します。

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

あなたが複数文字の文字列オブジェクトを持っていて、あなたが単一の文字を取った場合、それは文字列になるでしょう、そしてそれはエンコーディングによっては1バイト以上のサイズかもしれません。

1バイトをバイト文字列と一緒に取ると、0から255の範囲の1つの8ビット値が得られます。エンコードのためにこれらの文字が> 1バイトの場合、完全な文字を表すとは限りません。

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

15
gecko

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

r接頭辞はバックスラッシュを「解釈されない」ようにします(無視されず、違いは does 重要です)。

これは、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'プレフィックスを追加すると問題が解決します。

7
user3053230

サーバ側から、もし我々が何らかの応答を送るならば、それはバイトタイプの形で送られるでしょう。それはそれがb'Response from server 'としてクライアントに現れるでしょう。

B '....'を取り除くためには、単に以下のコードのサーバーファイルを使用してください

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

クライアントファイル

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

それが印刷されます

サーバーからの応答

6
Nani Chintha

他の人が言ったことに加えて、unicode の中の単一の文字は複数のバイト からなることができることに注意してください。

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
xjcl

あなたはそれを辞書に変換するためにJSONを使うことができます

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

{"キー": "値"}


フラスコ:

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

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

フラスコ内/ 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)

{'キー': '値'}

0
Karam Qusai