Bạn in ra file rồi đọc lại, rồi in lại ra terminal đúng không? Nếu bạn mở file output bằng text editor thì sẽ thấy chẳng có khác nhau gì cả.
Hoặc nhanh nhất là bạn đổi sang Python 3, Python 2 sắp đến hồi khai tử rồi.
Bạn in ra file rồi đọc lại, rồi in lại ra terminal đúng không? Nếu bạn mở file output bằng text editor thì sẽ thấy chẳng có khác nhau gì cả.
Hoặc nhanh nhất là bạn đổi sang Python 3, Python 2 sắp đến hồi khai tử rồi.
mình xem trên sublimetext thôi, chứ không xem trên terminal, khi lưu thì nó bị như vậy, mình dùng python3
cụ thể là mình đọc ghi file json, không biết có liên gì không?
trên đầu mình có ghi như này:
# -*- coding: utf8 -*-
Bạn đã encode string sang UTF-8 và mở file bằng encoding UTF-8 chưa?
bằng lệnh hay là chỉnh sửa phần mêm đọc file (sublime mình đang dùng) vậy
Xác nhận là do json nhé bạn. Json không lưu được trực tiếp các kí tự unicode mà phải lưu qua mã.
>>> json.dumps({"id":1, "text":"thử cái đã"})
'{"id": 1, "text": "th\\u1eed c\\u00e1i \\u0111\\u00e3"}'
vậy sự khác nhau là 1 cái đã được mã unicode đã được decode và 1 cái chưa được decode hả bạn.
mình có thử search trên mạng, sau khi thêm 2 dòng này thì mình đã làm được:
with open('data_book.json', 'w', encoding='utf-8') as outfile:
for f in data:
tmp = f['id'].split("_")
if(tmp[0] == "BOOK"):
json.dump(f, outfile, ensure_ascii=False)
outfile.write('\n')
thêm
encoding='utf-8'
ensure_ascii=False
lúc thì bạn dùng unicode lúc thì bạn dùng utf-8 mình chưa hiểu lắm
code trên là mình đang ghi vài file (mình cần write)
ngoài ra bạn giải thích cho mình, tại sao khi bạn dùng là unicode, khi bạn lại dùng là utf-8 vậy?
UTF-8 là viết tắt của 8-bit Unicode Transformation Format.
Unicode là…
Thường thì viết kí tự tiếng Việt vào file với encoding UTF-8.
vậy sự khác nhau giữa 2 loại mã utf-8 trên là gì vậy bạn :), mình đọc rồi nhưng chưa biết.
tr\u01b0\u1eddng
và
trường
trường
lưu xuống file vậy là đã có thông qua encoding (utf-8 hoặc utf-16 hoặc ucs-2 hoặc utf-32, v.v…)
tr\u01b0\u1eddng
là lưu ko có encoding. \u01b0
và \u1edd
là Unicode code point, bạn "\u1edd
code point" là ra “LATIN SMALL LETTER O WITH HORN AND GRAVE”
Unicode map mỗi ký tự với 1 số cố định gọi là code point, hiện tại có khoảng hơn 1.1 triệu code point. Các code point này được encode thành n bytes gọi là code value. Mỗi code point được encode thành bao nhiêu byte thì tùy theo encoding gì. Ví dụ:
tuy UCS-2 chỉ lưu được có 65k ký tự nhưng ngoài 65k ký tự này các ký tự khác rất ít khi xài. 65k ký tự đầu tiên này gọi là Basic Multilingual Plane (BMP).
sở dĩ có các encoding này là để tiết kiệm bộ nhớ: lưu trực tiếp code point thì tốn 6 bytes (\uxxxx với x là 1 số hệ 16) hoặc 4 bytes binary (1.1 triệu code points nên xài 32-bit integer), còn lưu nhờ các encoding kia thì tốn ít hơn (1-4 bytes 1 code point)
đừng nhầm lẫn Unicode với các encoding UTF-8 UTF-16 UTF-32 :V Ông nội Windows bị khùng, UCS-2 mà mấy ổng ghi là Unicode nên mới gây nhầm lẫn như vậy. Với người dùng bình thường họ ko biết thì ko sao, MS lừa được họ, còn lập trình viên thì phải biết phân biệt chiêu trò lừa đảo của MS :V :V Unicode ko liên quan gì tới encoding :V
khi lưu:
[ký tự] ----map Unicode----> [code point] ----encode----> [code value] ----write----> [file]
khi đọc:
[file] ----read----> [code value] ----decode----> [code point] ----map Unicode----> [ký tự]
thư viện json
của Python 3 có lẽ vì nó sợ user xài bậy :V lưu file ko có encode utf-8 hoặc encode ucs-2 :V :V nên nó mới mặc đình xài \uxxxx
như vậy, bảo đảm save/load với open(..., 'w')
luôn đúng.
UCS-2 = luôn là 16-bit (Windows)
UTF-8 = 8/16/24/32-bit (thông dụng nhất trên web)
UTF-16 = 16-bit || 32-bit
cám ơn tiền bối, cái gì cũng biết. giờ em mới biết khái niệm ucs-2, có search qua, thì thấy người ta đã bỏ nó rồi. Mà tiền bối viết như trên, em đọc vẫn còn mơ hồ quá.
Nổ não: ấ
là một kí tự gồm 2 code point đại diện cho â
và dấu sắc
Ờ, bỏ rồi!
Nếu xem trong Unikey, bạn sẽ thấy danh sách các Bảng mã, trong đó có:
\xhh
hay \uhhhh
gì đấy.Theo trí nhớ!
cái này là tổ hợp :V Combining character gì ấy, 1 cái hại não nữa của Unicode. 1 glyph có thể được ghép lại từ nhiều combining characters :V Do tiếng Việt số glyph hạn chế nên người ta gán code points luôn cho mấy chữ tiếng Việt, nhưng vẫn xài glyph ghép được :V
ghép 1 dấu sắc đã là gì :V :V https://lingojam.com/ZalgoText
d̴̖̘͖́̉̂͝͠͝a̶̤̓̇͠͠ý̴̠͚̤͇̈́̓̓̑̑ͅn̴̡͖͔̪̐̆̉̃͊̒͒̎h̷̨̢͔̜̼͕̙͖̏̅ä̵̧̦̟͍̲͔́͛̓̅̔̀͝͠ͅu̵̧̧̯͖̮͔̽̈́̔̈́̔̐͘͜h̸̠͍̿͆̇͆̏̽̈́̀o̶̠̦̱̾̊͛̏c̴̫͈̀̅́̃
con người viết chữ có ghép chữ lại với nhau thành ra Unicode cũng phải có vụ ghép này. Ghép đã rồi lại thấy từ ghép ít quá cho làm code point riêng luôn thành ra tiếng Việt có 2 cách viết ghép chữ và dấu và cách xài trực tiếp chữ có dấu :V
Các bạn có thể dùng cách này:
with open(Save_yml_path, 'w', encoding='utf-8') as yaml_file:
yaml.dump(Data_Dict_CoTiengViet, yaml_file, default_flow_style=False, allow_unicode=True, encoding='utf-8')