Saya mencoba untuk membangun objek byte ini di Python 3:
b'3\r\n'
jadi saya mencoba yang jelas (untuk saya), dan menemukan perilaku aneh:
>>> bytes(3) + b'\r\n'
b'\x00\x00\x00\r\n'
Tampaknya:
>>> bytes(10)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Saya tidak dapat melihat petunjuk tentang mengapa konversi byte bekerja dengan cara ini membaca dokumentasi. Namun, saya menemukan beberapa pesan kejutan dalam masalah Python ini tentang menambahkan format
ke byte (lihat juga pemformatan Python 3 byte ):
http://bugs.python.org/issue3982
Ini berinteraksi lebih buruk lagi dengan keanehan seperti byte (int) mengembalikan nol sekarang
dan:
Akan jauh lebih nyaman bagi saya jika byte (int) mengembalikan ASCIIfication dari int itu; tetapi jujur, bahkan kesalahan akan lebih baik daripada perilaku ini. (Jika saya menginginkan perilaku ini - yang tidak pernah saya miliki - saya lebih suka itu menjadi metode kelas, dipanggil seperti "bytes.zeroes (n)".)
Dapatkah seseorang menjelaskan kepada saya dari mana perilaku ini berasal?
sumber
3 .to_bytes
Jawaban:
Begitulah cara itu dirancang - dan itu masuk akal karena biasanya, Anda akan memanggil
bytes
iterable daripada integer tunggal:The docs menyatakan ini , serta docstring untuk
bytes
:sumber
bytes
hanyalah alias untukstr
, yang artinyabytes([3])
memberi Anda'[3]'
.bytes([n])
hanya berfungsi untuk int n dari 0 hingga 255. Untuk hal lain yang dimunculkanValueError
.bytes([3])
masih berbeda dari apa yang diinginkan OP - yaitu nilai byte yang digunakan untuk mengkodekan angka "3" dalam ASCII, yaitu.bytes([51])
, yangb'3'
tidakb'\x03'
.bytes(500)
membuat bytestring w / len == 500. Itu tidak membuat bytestring yang mengkodekan integer 500. Dan saya setuju itubytes([500])
tidak bisa bekerja, itulah sebabnya itu juga jawaban yang salah. Mungkin jawaban yang tepat adalahint.to_bytes()
untuk versi> = 3.1.Dari python 3.2 bisa Anda lakukan
https://docs.python.org/3/library/stdtypes.html#int.to_bytes
Dengan demikian
x == int_from_bytes(int_to_bytes(x))
,. Perhatikan bahwa pengodean ini hanya berfungsi untuk bilangan bulat (non-negatif) yang tidak ditandatangani.sumber
b"3"
dari3
, seperti pertanyaannya. (Ini akan memberib"\x03"
.)Anda dapat menggunakan paket struct :
">" Adalah byte-order (big-endian) dan "I" adalah karakter format . Jadi Anda bisa spesifik jika Anda ingin melakukan sesuatu yang lain:
Ini berfungsi sama pada kedua python 2 dan python 3 .
Catatan: operasi terbalik (byte ke int) dapat dilakukan dengan membongkar .
sumber
I
,H
, danB
bekerja sampai2**k - 1
di mana k adalah 32, 16, dan 8 masing-masing. Untuk input yang lebih besar, mereka meningkatkanstruct.error
.b'3\r\n'
, yaitu byte-string yang berisi karakter ASCII "3" bukan karakter ASCII "\ x03"\x03
, dan solusi jika Anda hanya inginb'3'
sepele. Alasan yang dikutip oleh ABB jauh lebih masuk akal ... atau setidaknya bisa dimengerti.bytes([x])
dan(x).to_bytes()
di Python 3.5. Itu tidak terduga.Python 3.5+ memperkenalkan% -interpolasi (-style
printf
format) untuk byte :Lihat PEP 0461 - Menambahkan format% ke byte dan bytearray .
Pada versi sebelumnya, Anda dapat menggunakan
str
dan.encode('ascii')
hasilnya:Catatan: Ini berbeda dari apa yang
int.to_bytes
menghasilkan :sumber
Dokumentasi mengatakan:
Urutannya:
Ini adalah karakter '3' (desimal 51) karakter '\ r' (13) dan '\ n' (10).
Oleh karena itu, cara akan memperlakukannya seperti itu, misalnya:
Diuji pada IPython 1.1.0 & Python 3.2.3
sumber
bytes(str(n), 'ascii') + b'\r\n'
ataustr(n).encode('ascii') + b'\r\n'
. Terima kasih! :)"{}\r\n".format(n).encode()
saya tidak berpikir ada salahnya dilakukan dengan menggunakan pengkodean utf8 defaultASCIIfikasi 3
"\x33"
tidak"\x03"
!Itulah yang python lakukan untuk
str(3)
tetapi akan benar-benar salah untuk byte, karena mereka harus dianggap array data biner dan tidak disalahgunakan sebagai string.Cara paling mudah untuk mencapai apa yang Anda inginkan adalah
bytes((3,))
, yang lebih baik daripadabytes([3])
karena menginisialisasi daftar jauh lebih mahal, jadi jangan pernah menggunakan daftar ketika Anda bisa menggunakan tuple. Anda dapat mengonversi bilangan bulat yang lebih besar dengan menggunakanint.to_bytes(3, "little")
.Menginisialisasi byte dengan panjang yang diberikan masuk akal dan merupakan yang paling berguna, karena mereka sering digunakan untuk membuat beberapa jenis buffer yang memerlukan memori yang dialokasikan untuk ukuran tertentu. Saya sering menggunakan ini ketika menginisialisasi array atau memperluas beberapa file dengan menulis nol padanya.
sumber
b'3'
adalahb'\x33'
, tidakb'\x32'
. (B)(3)
bukan tupel - Anda harus menambahkan koma. (C) Skenario inisialisasi urutan dengan nol tidak berlaku untukbytes
objek, karena mereka tidak berubah (masuk akal untukbytearray
s, meskipun).bytes
danbytearray
, saya pikir sebagian besar masalah konsistensi. Tetapi ini juga berguna jika Anda ingin mendorong beberapa angka nol ke dalam buffer atau file, dalam hal ini hanya digunakan sebagai sumber data.int
(termasuk Python2long
) dapat dikonversibytes
menggunakan fungsi berikut:Konversi terbalik dapat dilakukan oleh yang lain:
Kedua fungsi bekerja pada Python2 dan Python3.
sumber
Saya ingin tahu tentang kinerja berbagai metode untuk satu int dalam kisaran
[0, 255]
, jadi saya memutuskan untuk melakukan beberapa tes waktu.Berdasarkan timing bawah, dan dari kecenderungan umum saya amati dari mencoba banyak nilai dan konfigurasi yang berbeda,
struct.pack
tampaknya menjadi yang tercepat, diikuti olehint.to_bytes
,bytes
dan denganstr.encode
(mengejutkan) menjadi yang paling lambat. Perhatikan bahwa hasilnya menunjukkan lebih banyak variasi daripada yang diwakili, danint.to_bytes
danbytes
kadang - kadang beralih peringkat kecepatan selama pengujian, tetapistruct.pack
jelas yang tercepat.Hasil dalam CPython 3.7 di Windows:
Modul uji (bernama
int_to_byte.py
):sumber
[0, 255]
. Saya berasumsi dengan "indikator yang salah" yang Anda maksud pengukuran saya tidak cukup umum untuk memenuhi sebagian besar situasi? Atau apakah metodologi pengukuran saya buruk? Jika yang terakhir, saya akan tertarik untuk mendengar apa yang Anda katakan, tetapi jika yang pertama, saya tidak pernah mengklaim pengukuran saya generik untuk semua kasus penggunaan. Untuk situasi saya (mungkin niche), saya hanya berurusan dengan int dalam kisaran[0, 255]
, dan itu adalah audiens yang saya maksudkan dengan jawaban ini. Apakah jawaban saya tidak jelas? Saya dapat mengeditnya untuk kejelasan ...bytes((i,))
alih-alihbytes([i])
karena daftar lebih kompleks, menggunakan lebih banyak memori dan butuh waktu lama untuk menginisialisasi. Dalam hal ini, untuk apa-apa.Meskipun jawaban sebelumnya oleh brunsgaard adalah pengkodean yang efisien, ia hanya berfungsi untuk bilangan bulat yang tidak ditandai. Yang ini dibangun untuk bekerja untuk bilangan bulat yang ditandatangani dan tidak ditandatangani.
Untuk encoder,
(i + ((i * signed) < 0)).bit_length()
digunakan bukan hanyai.bit_length()
karena yang terakhir mengarah pada pengkodean -128, -32768 yang tidak efisien, dll.Kredit: CervEd untuk memperbaiki inefisiensi kecil.
sumber
int_to_bytes(-128, signed=True) == (-128).to_bytes(1, byteorder="big", signed=True)
adalahFalse
-128
,-32768
dll.(i+(signed*i<0)).bit_length()
Perilaku ini berasal dari fakta bahwa dalam Python sebelum versi 3
bytes
hanyalah alias untukstr
. Dalam Python3.xbytes
adalah versi abadibytearray
- tipe yang sama sekali baru, tidak kompatibel.sumber
Dari byte dokumen :
Kemudian, dari bytearray docs :
Perhatikan, itu berbeda dari perilaku 2.x (di mana x> = 6), di mana
bytes
hanyastr
:PEP 3112 :
sumber
Beberapa jawaban tidak bekerja dengan jumlah besar.
Konversikan integer ke representasi hex, lalu konversikan ke byte:
Hasil:
sumber
int.to_bytes
bekerja dengan bilangan bulat apa pun.Jika pertanyaannya adalah bagaimana mengubah bilangan bulat itu sendiri (bukan string yang setara) menjadi byte, saya pikir jawabannya adalah:
Informasi lebih lanjut tentang metode ini di sini:
sumber