'B' karakteri bir dizgi değişmezinin önünde ne yapar?


831

Görünüşe göre, aşağıdaki sözdizimi şöyledir:

my_string = b'The string'

Bilmek isterim:

  1. bDizenin önündeki bu karakter ne anlama geliyor?
  2. Kullanmanın etkileri nelerdir?
  3. Kullanmak için uygun durumlar nelerdir?

Burada SO ile ilgili bir soru buldum , ancak bu soru PHP ile ilgili olsa da ve bkodun PHP <6 sürümünden uyumlu olması için gerekli olan Unicode'un aksine dizenin ikili olduğunu belirtmek için kullanıldığını belirtir. , PHP 6'ya geçerken. Bunun Python için geçerli olduğunu düşünmüyorum.

Unicode olarak bir dize belirtmek için aynı sözdiziminde bir karakter kullanma hakkında Python sitesinde bu belgeleri buldum u. Ne yazık ki, belgenin hiçbir yerinde b karakterinden bahsetmiyor .

Ayrıca, sadece meraktan, daha sembolleri vardır bve uo başka şeyler yapmak?

Yanıtlar:


416

Python 2.x belgelerini alıntılamak için :

Python 2'de 'b' veya 'B' öneki yok sayılır; değişmez değerin Python 3'te bir bayt değişmez değeri olması gerektiğini belirtir (örneğin, kod otomatik olarak 2to3 ile dönüştürüldüğünde). Bir 'u' veya 'b' önekinin ardından bir 'r' öneki gelebilir.

Python 3 dokümantasyon durumları:

Bayt değişmezlerine her zaman 'b' veya 'B' öneki eklenir; str türü yerine bayt türünün bir örneğini oluştururlar. Yalnızca ASCII karakterleri içerebilirler; 128 veya daha büyük sayısal değere sahip baytlar, çıkış karakterleriyle ifade edilmelidir.


4
Bu yüzden Python <v3 bu ekstra karakteri görmezden gelecek gibi görünüyor. V3'te normal bir dize yerine ab dizesini kullanmanız gereken bir durum ne olurdu?
Jesse Webb

5
@Gweebz - aslında unicode kaçışları yerine belirli bir kodlamaya bir dize yazıyorsanız (ör. '\ U32e1' yerine b '\ xff \ xfe \ xe12').
detly

7
İçe aktardığınız Aslında, eğer unicode_literalsgelen __future__bu (Python 2.x) bu özel dize için davranışını "ters" olacak
Romuald Brunet

34
Alıntılanan belgeler etrafında biraz daha basit bir dil anlatımı, bu daha iyi bir cevap olacaktır IMHO
Hack-R

2
Aksi takdirde, zaten anlayan biri için bir cevaptır.
Rafael Eyng

679

Python 3.x , türler arasında net bir ayrım yapar:

  • str= '...'değişmez değerler = bir Unicode karakter dizisi (Python'un nasıl derlendiğine bağlı olarak UTF-16 veya UTF-32)
  • bytes= b'...'değişmez değerler = bir sekizli dizisi (0 ile 255 arasında tamsayılar)

Java veya C # ile konum tanıdık Eğer varsa, aklınıza strolarak Stringve bytessıra byte[]. Eğer SQL ile bilginiz varsa, düşünmek strkadar NVARCHARve bytesşekilde BINARYya BLOB. Windows kayıt defteri hakkında bilginiz varsa, düşünmek strkadar REG_SZve bytesşekilde REG_BINARY. C (++) hakkında bilginiz varsa, öğrendiğiniz her şeyi charve dizeleri unutun , çünkü KARAKTER BİR BYTE DEĞİLDİR . Bu fikir çok eski.

Sen kullanmak strMetni temsil etmek istediğinizde.

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

Sen kullanmak bytesEğer yapılar gibi düşük seviyeli ikili veri temsil etmek istediğinizde.

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

Sen edebilirsiniz kodlamak bir stra bytesnesne.

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

Ve eğer bir deşifre edebilir bytesbir içine str.

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

Ancak iki türü serbestçe karıştıramazsınız.

>>> 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'...'Notasyonu biraz o ASCII karakterleri yerine onaltılık numaraları ile belirtilmesi 0x01-0x7F bayt izin vermesidir karıştırıyor.

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

Ama vurgulamalıyım ki, karakter bir bayt değildir .

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

Python 2.x'te

Python'un 3.0 öncesi sürümlerinde metin ve ikili veriler arasında bu tür bir ayrım yoktu. Bunun yerine:

  • unicode= u'...'değişmez değerler = Unicode karakter dizisi = 3.xstr
  • str= '...'değişmez değerler = şaşkın bayt / karakter dizileri
    • Genellikle metin, bazı belirtilmemiş kodlamalarda kodlanır.
    • Ancak struct.packçıktı gibi ikili verileri temsil etmek için de kullanılır .

2.x-3.x geçişini kolaylaştırmak için, b'...'ikili dizelerin ( bytes3.x içinde olması gerekir ) metin dizelerinden ( str3'te olması gerekir) ayırt edilmesini sağlamak için değişmez sözdizimi Python 2.6'ya geri bildirildi . .x). bÖnek 2.x hiçbir şey yapmaz, ama söyler 2to33.x Unicode dizeye dönüştürmek için değil senaryoyu

Yani evet, b'...'Python'daki değişmez değerler PHP ile aynı amaca sahiptir.

Ayrıca, meraktan, diğer şeyleri yapan b ve u'dan daha fazla sembol var mı?

Ön rek, ham dize oluşturur (örneğin, sekme yerine r'\t'ters eğik çizgi + 'dır t) ve üç tırnak işareti verir '''...'''veya """..."""çok satırlı dize değişmez değerlerine izin verir.


2
Teşekkürler! Bunu şu cümleleri okuduktan sonra anladım: "2.x-3.x geçişini kolaylaştırmak için, b '...' değişmez sözdizimi Python 2.6'ya aktarıldı. metin dizelerinden (3.x'te str olması gerekir) byte olmalıdır. b öneki 2.x'te hiçbir şey yapmaz, ancak 2to3 komut dosyasına 3.x'te bir Unicode dizesine dönüştürmemesini söyler. "
tommy.carstensen

4
'A' == b'A' --> FalseÇek gerçekten o temizlemek yapar. Geri kalanı mükemmel, ama o zamana kadar bir bayt dizesinin gerçekten metin
Joker

12
'שלום עולם' == 'hello world'
Eli

12
Bu, sadece dokümantasyondan alıntılanan kabul edilen cevaptan çok daha açıktır. Benim için bir anlam ifade etmediği için dokümantasyonda daha fazla bağlam sağlamak harika. Teşekkürler!
rayryeng

2
b "bazı dize" .decode ('UTF-8'), birçok kişinin aradığı çizginin bu olduğuna inanıyorum
Marvin Thobejane

22

B bir bayt dizesini belirtir.

Bayt gerçek verilerdir. Dizeler bir soyutlamadır.

Çok karakterli dize nesneniz varsa ve tek bir karakter aldıysanız, bu bir dize olur ve kodlamaya bağlı olarak 1 bayttan daha büyük olabilir.

Bir bayt dizesiyle 1 bayt alınırsa, 0-255 arasında tek bir 8 bit değer alırsınız ve kodlama nedeniyle bu karakterler> 1 baytsa tam bir karakter göstermeyebilir.

TBH Bayt kullanmak için belirli bir düşük düzey nedenim olmadıkça dizeleri kullanırdım.


16

Sunucu tarafından, herhangi bir yanıt gönderirsek, bayt türü biçiminde gönderilir, böylece istemcide şu şekilde görünür: b'Response from server'

Kurtulmak b'....'için aşağıdaki kodu kullanın:

Sunucu dosyası:

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

İstemci dosyası:

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

o zaman yazdıracak Response from server


1
Jesse Webb'in sorduğu soruyu açıklamıyor!
Chandra Kanth

Kodlama ve kod çözme yöntemlerini kullanmadan, dize çıktısının p 'olarak dize türü yerine bir bayt türü olarak alması için b' 'önekinin olacağını söylüyordum. B' gibi bir çıktı almak istemiyorsanız ... 'Yukarıdakileri kullanın, ne anlamadınız?
Nani Chintha

Aslında bu tam olarak sorulan sorunun başlığının cevabıdır : S: "b'x 'ne yapar?" C: '' x'.encode () '' işte tam anlamıyla bunu yapar. Sorunun geri kalanı bundan daha fazlasını bilmek istedi, ancak başlık cevaplandı.
Michael Erickson

10

Python 3.x'te yokluğun istisna bedeceği bir örnekTypeError

>>> 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

Bir bönek eklemek sorunu çözer.


9

Bunu bir bytesdeğişmez şekle (veya str2.x'te) dönüştürür ve 2.6+ için geçerlidir.

rÖnek ters eğik çizgi "Uninterpreted" neden olur (göz ardı ve fark yapar madde).


Bu, aix'in cevabında belirtilen belgelere göre yanlış geliyor; b 3 dışındaki Python sürümünde yok sayılır.
Jesse Webb

2
Her striki şekilde de bir 2.x olacak, bu yüzden göz ardı edildiği söylenebilir. İçe zaman ayrım önemli unicode_literalsgelen __future__modül.
Ignacio Vazquez-Abrams

6

Diğerlerinin söylediklerine ek olarak, unicode'daki tek bir karakterin birden fazla bayt içerebileceğini unutmayın .

Unicode'un çalışma şekli, eski ASCII biçimini (0xxx xxxx gibi görünen 7 bit kod) aldı ve tüm baytların ASCII'nin ötesindeki karakterleri temsil etmek için tüm baytların 1 (1xxx xxxx) ile başladığı çoklu bayt dizileri eklemesidir, böylece Unicode geriye dönük olur uyumlu bir ASCII ile.

>>> 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'u sözlüğe çevirmek için kullanabilirsiniz

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

{ "Anahtar": "bir değer"}


ŞİŞELERİNİ:

Bu şişeden bir örnek. Bunu terminal hattında çalıştırın:

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

Şişede / route.py içinde

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

{ 'Anahtar': 'değer'}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.