Python 3'te dizeyi bayta dönüştürmenin en iyi yolu?

https://stackoverflow.com/questions/5471158/typeerror-str-does-not-support-the-buffer-interface adresindeki yanıtlarda görüldüğü gibi, bir dizeyi bayta dönüştürmenin iki farklı yolu var gibi görünüyor

Bu yöntemlerden hangisi daha iyi veya daha Pythonic olurdu? Yoksa bu sadece kişisel bir tercih meselesi mi?

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

b = mystring.encode('utf-8')
Çözüm

Eğer bytes için dokümanlara bakarsanız, sizi bytearray adresine yönlendirir:

bytearray([kaynak[, kodlama[, hatalar]])

Yeni bir bayt dizisi döndürür. Bytearray türü, 0 <= x < 256 aralığındaki tamsayıların değiştirilebilir bir dizisidir. Mutable Sequence Types bölümünde açıklanan mutable dizilerin olağan yöntemlerinin çoğuna ve bytes türünün sahip olduğu yöntemlerin çoğuna sahiptir, Bytes and Byte Array Methods bölümüne bakınız.

İsteğe bağlı kaynak parametresi, diziyi birkaç farklı şekilde başlatmak için kullanılabilir:

Eğer bir dizeyse, kodlama (ve isteğe bağlı olarak hatalar) parametrelerini de vermelisiniz; bytearray() daha sonra str.encode() kullanarak dizeyi baytlara dönüştürür.__

Eğer bir tamsayı ise, dizi bu boyuta sahip olacak ve null bayt ile başlatılacaktır.

Tampon arayüzüne uygun bir nesne ise, bayt dizisini başlatmak için nesnenin salt okunur bir tamponu kullanılacaktır.

Eğer bir yinelenebilir ise, dizinin ilk içeriği olarak kullanılan 0 Bir argüman olmadan, 0 boyutlu bir dizi oluşturulur.__

Yani bytes bir dizeyi kodlamaktan çok daha fazlasını yapabilir. Pythonic, yapıcıyı mantıklı olan herhangi bir kaynak parametre türüyle çağırmanıza izin verecektir.

Bir dizgiyi kodlamak için, some_string.encode(encoding) yapıcıyı kullanmaktan daha Pythonic olduğunu düşünüyorum, çünkü en çok kendini belgeliyor -- "bu dizgiyi al ve bu kodlama ile kodla" bytes(some_string, encoding)'den daha açık -- yapıcıyı kullandığınızda açık bir fiil yok.

Düzenleme: Python kaynağını kontrol ettim. CPython kullanarak bytes'a bir unicode string iletirseniz, encode'un uygulaması olan PyUnicode_AsEncodedString'i çağırır; yani encode'u kendiniz çağırırsanız sadece bir dolaylama seviyesini atlamış olursunuz.

Ayrıca, Serdalis' yorumuna bakın -- unicode_string.encode(encoding) aynı zamanda daha Pisoniktir çünkü tersi byte_string.decode(encoding) ve simetri güzeldir.

Yorumlar (5)

Düşünüldüğünden daha kolaydır:

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
Yorumlar (10)

Kesinlikle en iyi yol bu ikisinden biri değil, üçüncüsüdür. Python 3.0'dan beri encode defaults to* 'utf-8' için ilk parametre. Bu nedenle en iyi yol

b = mystring.encode()

Bu aynı zamanda daha hızlı olacaktır, çünkü varsayılan argüman C kodunda "utf-8" dizesiyle değil, kontrol edilmesi çok daha hızlı olan NULL ile sonuçlanır!

İşte bazı zamanlamalar:

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

Uyarıya rağmen, tekrarlanan çalıştırmalardan sonra süreler çok istikrarlıydı - sapma sadece ~ yüzde 2 idi.


Python 2'de varsayılan karakter kodlaması ASCII olduğu için encode() işlevini argüman olmadan kullanmak Python 2 ile uyumlu değildir.

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