Bagaimana cara mengubah representasi string Python dari string byte menjadi string byte yang sebenarnya? [duplikat]

Saya mencoba mencari cara bagaimana seseorang dapat mengubah representasi string dari string-byte menjadi tipe string-byte yang sebenarnya. Saya tidak terlalu terbiasa dengan Python (hanya meretasnya untuk membantu teman), jadi saya tidak yakin apakah ada metode "casting" yang mudah (seperti yang dimiliki Java kesayangan saya;)). Pada dasarnya saya memiliki file teks, yang isinya string byte:

b'\x03\xacgB\x16\xf3\xe1\\v\x1e\xe1\xa5\xe2U\xf0g\x956#\xc8\xb3\x88\xb4E\x9e\x13\xf9x\xd7\xc8F\xf4'

Saat ini saya membaca file ini sebagai berikut:

aFile = open('test.txt')
x = aFile.read()
print(x) # prints b'\x03\xacgB\x16\xf3\xe1\\v\x1e\xe1\xa5\xe2U\xf0g\x956#\xc8\xb3\x88\xb4E\x9e\x13\xf9x\xd7\xc8F\xf4'
print(type(x)) # prints <class 'str'>

Bagaimana cara membuat x menjadi tipe <class 'bytes'>? Terima kasih atas bantuannya.

Sunting: Setelah membaca salah satu balasan di bawah, saya rasa saya mungkin terlalu membatasi pertanyaannya. Saya minta maaf untuk itu. String masukan tidak harus dalam format string byte python (yaitu dengan b dan tanda kutip), bisa saja berupa string byte biasa:

\x03\xacgB\x16\xf3\xe1\\v\x1e\xe1\xa5\xe2U\xf0g\x956#\xc8\xb3\x88\xb4E\x9e\x13\xf9x\xd7\xc8F\xf4

Jika ini membuatnya lebih mudah atau merupakan latihan yang lebih baik, saya bisa menggunakan ini.


person Stephen    schedule 12.03.2011    source sumber
comment
Tidak ada casting dengan Python, konsepnya benar-benar tidak masuk akal dalam bahasa yang dinamis. Itu semua mengetik bebek. Jika terlihat seperti str dan berjalan seperti str, Anda menganggapnya str. Lagi pula, bagaimana Anda melakukan cast ini? Jika Anda mentransmisikannya ke str, Anda akan mendapatkan str yang dimulai dengan b'\x. :)   -  person Lennart Regebro    schedule 12.03.2011


Jawaban (2)


Karena masukan Anda dalam sintaksis Python, untuk beberapa alasan (*), yang harus dilakukan di sini hanyalah memanggil eval:

>>> r"b'\x12\x12'"
"b'\\x12\\x12'"
>>> eval(r"b'\x12\x12'")
'\x12\x12'

Namun berhati-hatilah, karena ini mungkin merupakan masalah keamanan. eval akan menjalankan kode apa pun, jadi Anda mungkin perlu membersihkan inputnya. Dalam kasus Anda, ini sederhana - cukup periksa apakah yang Anda eval-ingkan memang berupa string dalam format yang Anda harapkan. Jika keamanan tidak menjadi masalah di sini, jangan repot-repot.

Mengulang EDIT Anda: Namun, eval adalah pendekatan paling sederhana di sini (setelah menambahkan b'' jika tidak ada). Anda juga dapat, tentu saja, melakukan ini secara manual dengan mengonversi setiap \xXX ke nilai sebenarnya.


(*) Sebenarnya kenapa? Ini sepertinya pilihan yang aneh untuk format representasi data

person Eli Bendersky    schedule 12.03.2011
comment
Alasan yang baru kusadari adalah alasan yang sangat bodoh. XD. Menyimpan nilai hash saat bermain-main, tidak berpikir untuk menggunakan .hexdigest() daripada digest(). hexdigest() tentu saja memberikan sebuah string, yang jauh lebih bagus untuk dimainkan. Maaf mengganggu Anda dengan pertanyaan konyol. - person Stephen; 12.03.2011
comment
@Stephen: tidak apa-apa, selama Anda mendapat bantuan ;-) Memiliki format seperti ini adalah bau kode yang jelas, jadi saya tunjukkan - person Eli Bendersky; 12.03.2011
comment
@Stephen: Byte bagus untuk dimainkan (tapi oke, mungkin tidak sebaik itu), pertanyaannya adalah mengapa Anda menulis representasi byte ke file, bukan byte itu sendiri. - person Lennart Regebro; 12.03.2011

>>> r'\x03\xacgB\x16\xf3\xe1\\v\x1e\xe1\xa5\xe2U\xf0g\x956#\xc8\xb3\x88\xb4E\x9e\x13\xf9x\xd7\xc8F\xf4'.decode('string-escape')
'\x03\xacgB\x16\xf3\xe1\\v\x1e\xe1\xa5\xe2U\xf0g\x956#\xc8\xb3\x88\xb4E\x9e\x13\xf9x\xd7\xc8F\xf4'

Ini akan berfungsi untuk string yang tidak memiliki b'...' di sekitarnya. Jika tidak, Anda dianjurkan untuk menggunakan ast.literal_eval().

person Ignacio Vazquez-Abrams    schedule 12.03.2011
comment
Untuk alasan di luar jangkauan saya, ast.literal_eval() tidak berfungsi untuk b'' literal di Python 3.x -- itu sebabnya saya menghapus jawaban saya. - person Sven Marnach; 12.03.2011
comment
@Sven: Aneh. Berfungsi dengan baik di 2.7. - person Ignacio Vazquez-Abrams; 12.03.2011
comment
@Sven: Hah, kamu benar. Tahukah Anda jika ada laporan bug terbuka untuk itu? - person ncoghlan; 12.03.2011
comment
@Sven: literal_eval tampaknya dapat menangani byte dari 3.2. Tidak tahu mengapa itu dihilangkan sebelumnya. - person Thomas K; 12.03.2011
comment
seharusnya .decode('unicode_escape') di Python3. - person jfs; 12.03.2011
comment
... yang harus dipanggil pada objek bytes, dan harus diikuti oleh .encode('latin-1') untuk mendapatkan objek bytes yang dimaksud. - person Miles; 14.03.2011