2015-07-17 14 views
6

Tôi đang sử dụng Python 3 (gần đây đã chuyển từ Python 2). Mã của tôi thường chạy trên Linux nhưng đôi khi (không thường xuyên) trên Windows. Theo tài liệu Python 3 cho open(), mã hóa mặc định cho tệp văn bản là từ locale.getpreferredencoding() nếu số encoding arg không được cung cấp. Tôi muốn giá trị mặc định này là utf-8 cho một dự án của tôi, bất kể hệ điều hành nào đang chạy (hiện tại, nó luôn là UTF-8 cho Linux, nhưng không phải cho Windows). Dự án có nhiều cuộc gọi đến open() và tôi không muốn thêm encoding='utf-8' vào tất cả các cuộc gọi đó. Vì vậy, tôi muốn thay đổi mã hóa ưa thích của ngôn ngữ trong Windows, như Python 3 thấy nó.Thay đổi “mã hóa ưu tiên miền địa phương” trong Python 3 trong Windows

Tôi đã tìm thấy câu hỏi trước "Changing the "locale preferred encoding"", trong đó có câu trả lời được chấp nhận, vì vậy tôi nghĩ mình nên đi. Nhưng thật không may, cả hai lệnh được đề xuất trong câu trả lời đó và bình luận đầu tiên của nó làm việc cho tôi trong Windows. Cụ thể, câu trả lời được chấp nhận và nhận xét đầu tiên của tôi đề xuất chạy chcp 65001set PYTHONIOENCODING=UTF-8 và tôi đã thử cả hai. Xin vui lòng xem bảng dưới đây từ cửa sổ cmd của tôi:

> py -i 
Python 3.4.3 ... 
>>> f = open('foo.txt', 'w') 
>>> f.encoding 
'cp1252' 
>>> exit() 

> chcp 65001 
Active code page: 65001 

> py -i 
Python 3.4.3 ... 
>>> f = open('foo.txt', 'w') 
>>> f.encoding 
'cp1252' 
>>> exit() 

> set PYTHONIOENCODING=UTF-8 

> py -i 
Python 3.4.3 ... 
>>> f = open('foo.txt', 'w') 
>>> f.encoding 
'cp1252' 
>>> exit() 

Lưu ý rằng ngay cả sau khi cả hai lệnh đề nghị, mã hóa tập tin mở của tôi vẫn là cp1252 thay vì dành utf-8.

+0

Có lẽ nó chỉ là phong cách của tôi nhưng tôi muốn viết một hàm wrapper() mà bạn chỉ định mã hóa. –

+0

Không sử dụng 'chcp 65001'. Bàn điều khiển Windows không hỗ trợ đúng UTF-8 và nó không làm những gì bạn muốn. 'locale.getpreferredencoding' không có gì để làm với bảng điều khiển codepage; nó dựa trên mã hóa ANSI của miền địa phương. Ví dụ: nếu bạn gọi Win32 'CreateFileA' (ANSI) thay vì' CreateFileW' (UTF-16), chuỗi đường dẫn tệp được giải mã dưới dạng chuỗi ANSI (ví dụ: Windows-1252). Windows không cho phép sử dụng UTF-8 làm bộ ký tự ANSI và thời gian chạy C cũng không cho phép sử dụng UTF-8 cho một ngôn ngữ. – eryksun

+0

@eryksun Cảm ơn bạn đã biết thông tin, nhưng nó có quá nhiều thuật ngữ dành riêng cho Windows đối với tôi. Tôi hiếm khi sử dụng Windows. Tất cả những gì tôi muốn là một cách để nói với Windows 8 hoặc Python 3: "Kính gửi Windows 8/Python 3, Vui lòng lưu ý rằng tất cả các tệp văn bản trên máy tính này phải được mã hóa bằng UTF-8 mà không có ngoại lệ. trong tương lai khi mở tệp văn bản. Cảm ơn. " – walrus

Trả lời

3

tôi biết một workaround hacky thật, nhưng bạn có thể xác định lại locale.getpreferredencoding() chức năng như vậy:

import locale 
def getpreferredencoding(do_setlocale = True): 
    return "utf-8" 
locale.getpreferredencoding = getpreferredencoding 

nếu bạn chạy này từ rất sớm, tất cả các file mở sau (ít kẻo trong thử nghiệm của tôi trên một win xp máy) mở trong utf-8, và khi điều này ghi đè lên phương thức mô-đun, điều này sẽ áp dụng cho tất cả các nền tảng.

+0

Tôi đã thử nghiệm nó trên python 3.5.1 và windows 7 và [có một cái nhìn] (http://stackoverflow.com/a/34345136/4933641) những gì tôi đã kết thúc với. – axil

3

Tính đến python3.5.1 hack này trông như thế này:

import _locale 
_locale._getdefaultlocale = (lambda *args: ['en_US', 'utf8']) 

Tất cả các file được mở sau đó sẽ giả mã hóa mặc định là utf8.

+0

Hoặc tốt hơn, 'utf_8_sig' vì nó sẽ chăm sóc ký tự BOM mà một số biên tập viên Windows có xu hướng chèn vào các tệp ngay cả khi mã hóa trung lập như 'utf8'. – axil

Các vấn đề liên quan