Saya bertanya-tanya apakah ada cara untuk memuat objek yang diasamkan di Python 2.4, dengan Python 3.4.
Saya telah menjalankan 2to3 pada sejumlah besar kode warisan perusahaan untuk mendapatkan yang terbaru.
Setelah melakukan ini, saat menjalankan file saya mendapatkan kesalahan berikut:
File "H:\fixers - 3.4\addressfixer - 3.4\trunk\lib\address\address_generic.py"
, line 382, in read_ref_files
d = pickle.load(open(mshelffile, 'rb'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1: ordinal
not in range(128)
Melihat objek acar dalam pertikaian, itu adalah dict
dalam dict
, berisi kunci dan nilai-nilai jenis str
.
Jadi pertanyaan saya adalah: Apakah ada cara untuk memuat objek, awalnya asinan dengan python 2.4, dengan python 3.4?
json
modul? Mungkin Anda bisa menulis skrip 2.4 yang menghapus objek dan menyimpannya sebagai objek json, dan kemudian menulis skrip 3.4 yang membaca objek json dan menyimpannya sebagai objek acar yang kompatibel dengan 3.4. Ini akan menjadi operasi satu kali yang Anda jalankan pada semua file acar Anda.Jawaban:
Anda harus memberi tahu
pickle.load()
cara mengonversi data bytestring Python ke string Python 3, atau Anda dapat memberi tahupickle
untuk membiarkannya sebagai byte.Standarnya adalah mencoba dan mendekode semua data string sebagai ASCII, dan gagal mendekode itu. Lihat
pickle.load()
dokumentasi :Mengatur pengodean ke
latin1
memungkinkan Anda untuk mengimpor data secara langsung:tetapi Anda harus memverifikasi bahwa tidak ada string Anda yang diterjemahkan menggunakan codec yang salah; Latin-1 berfungsi untuk input apa pun karena memetakan nilai byte 0-255 ke 256 titik kode Unicode pertama secara langsung.
Alternatifnya adalah memuat data dengan
encoding='bytes'
, dan mendekode semuabytes
kunci dan nilai sesudahnya.Perhatikan bahwa hingga versi Python sebelum 3.6.8, 3.7.2 dan 3.8.0, pembongkaran
datetime
data objek Python 2 rusak kecuali jika Anda menggunakanencoding='bytes'
.sumber
encoding
kata kunci sama sekali untuk Python 2.'encoding': 'latin1'
dan mengirim ** pickle_options ke acar. Dengan cara ini harus dijalankan di kedua versi.datetime
komentar itu bukanlah dorongan utama dari jawaban ini, tetapi bagi pembaca di masa mendatang, saya ingin menunjukkan bahwa bahkan versi "tetap" dari Python 3 masih perluencoding='latin-1'
membongkar datetime Python 2. Jika data acar Python 2 Anda kebetulan menyertakan datetimes dan bytestrings yang dikodekan dalam sesuatu selain Latin-1, maka Anda mungkin masih lebih baik menggunakanencoding='bytes'
setelah semua.Menggunakan
encoding='latin1'
menyebabkan beberapa masalah saat objek Anda berisi array numpy di dalamnya.Menggunakan
encoding='bytes'
akan lebih baik.Silakan lihat jawaban ini untuk penjelasan lengkap tentang penggunaan
encoding='bytes'
sumber
bytes
make strings menjadi byte (), jadi saya lebih sukalatin1
jika mungkin, tetapi tidak jelas bagi saya apa masalahnya.numpy.ndarray
acar dua dimensi (numpy 1,14) menggunakan Python 2.7cPickle.dumps()
, dan membongkar Python 3 denganpickle.loads(..., encoding='latin1')
berfungsi dengan baik.