Vấn đề này thường xảy ra khi chuyển từ py2 sang py3. Trong py2 plaintext
có cả kiểu chuỗi và kiểu byte . Trong py3 plaintext
chỉ là một chuỗi và phương thức outfile.write()
thực sự lấy một mảng byte khi outfile
được mở ở chế độ nhị phân, do đó, một ngoại lệ được đưa ra. Thay đổi đầu vào thànhplaintext.encode('utf-8')
để khắc phục vấn đề. Đọc nếu điều này làm phiền bạn.
Trong py2, khai báo cho file.write làm cho có vẻ như bạn đã truyền vào một chuỗi : file.write(str)
. Trên thực tế bạn đã truyền vào một mảng byte, bạn nên đọc phần khai báo như thế này : file.write(bytes)
. Nếu bạn đọc nó như thế này thì vấn đề rất đơn giản, file.write(bytes)
cần một loại byte và trong py3 để lấy byte ra khỏi str bạn chuyển đổi nó:
py3>> outfile.write(plaintext.encode('utf-8'))
Tại sao các tài liệu py2 tuyên bố file.write
lấy một chuỗi? Trong py2, sự phân biệt khai báo không thành vấn đề bởi vì:
py2>> str==bytes #str and bytes aliased a single hybrid class in py2
True
Lớp str-byte của py2 có các phương thức / hàm tạo làm cho nó hoạt động giống như một lớp chuỗi theo một số cách và một lớp mảng byte theo các cách khác. Thuận tiện cho file.write
nó không?:
py2>> plaintext='my string literal'
py2>> type(plaintext)
str #is it a string or is it a byte array? it's both!
py2>> outfile.write(plaintext) #can use plaintext as a byte array
Tại sao py3 phá vỡ hệ thống tốt đẹp này? Vâng, bởi vì trong các hàm chuỗi cơ bản py2 không hoạt động với phần còn lại của thế giới. Đo độ dài của một từ với một ký tự không phải ASCII?
py2>> len('¡no') #length of string=3, length of UTF-8 byte array=4, since with variable len encoding the non-ASCII chars = 2-6 bytes
4 #always gives bytes.len not str.len
Tất cả thời gian này bạn nghĩ rằng bạn đang yêu cầu len của một chuỗi trong py2, bạn đã nhận được độ dài của mảng byte từ mã hóa. Sự mơ hồ đó là vấn đề cơ bản với các lớp nhiệm vụ kép. Phiên bản nào của cuộc gọi phương thức nào bạn thực hiện?
Tin tốt sau đó là py3 đã khắc phục vấn đề này. Nó loại bỏ các lớp str và byte . Lớp str có các phương thức giống như chuỗi, lớp byte riêng biệt có các phương thức mảng byte:
py3>> len('¡ok') #string
3
py3>> len('¡ok'.encode('utf-8')) #bytes
4
Hy vọng biết điều này sẽ giúp giải quyết vấn đề và làm cho nỗi đau di cư trở nên dễ dàng hơn một chút.