2014-07-22 13 views
5

Tôi có thể thay đổi mặc định open()(io.open() in 2.7) mã hóa văn bản theo cách đa nền tảng không?Có cách nào để thay đổi mã hóa văn bản mặc định mở của Python() không?

Vì vậy mà tôi không cần phải chỉ định mỗi lần open(...,encoding='utf-8').

Trong chế độ văn bản, nếu mã hóa không được xác định mã hóa sử dụng là nền tảng phụ thuộc: locale.getpreferredencoding(False) được gọi là để có được mã hóa địa phương hiện tại.

Mặc dù tài liệu không chỉ định cách đặt mã hóa ưu tiên. Chức năng là trong mô-đun locale, vì vậy tôi cần phải thay đổi miền địa phương? Có cách nào đáng tin cậy trên nhiều nền tảng để đặt ngôn ngữ UTF-8 không? Nó sẽ ảnh hưởng đến bất cứ điều gì khác hơn là mã hóa tập tin văn bản mặc định?

Hoặc locale thay đổi này là nguy hiểm (có thể phá vỡ một cái gì đó), và tôi nên dính vào wrapper tùy chỉnh như:

def uopen(*args, **kwargs): 
    return open(*args, encoding='UTF-8', **kwargs) 

Trả lời

3

Không thay đổi ngôn ngữ hoặc mã hóa ưu tiên vì;

  • nó có thể ảnh hưởng đến các phần khác của mã của bạn (hoặc các thư viện bạn đang sử dụng); và
  • nó sẽ không rõ ràng rằng mã của bạn phụ thuộc vào open bằng cách sử dụng một mã hóa cụ thể.

Thay vào đó, sử dụng một wrapper đơn giản:

from functools import partial 
open_utf8 = partial(open, encoding='UTF-8') 

này có hai ưu điểm khác:

  • Bạn có thể chỉ định giá trị mặc định cho tất cả các đối số từ khóa (bạn nên cần).
  • Bạn có thể ghi đè các giá trị mặc định khi gọi chức năng.
+0

Đó là cách phù hợp để bao bọc các chức năng. +1 – user

+0

Tôi đã thử 'locale.setlocale()' và nó không thay đổi mã hóa mặc định trên Windows. Ngay cả với một không phải Unicode khác. Vì vậy, tôi quyết định kiểm tra mã nguồn của CPython và phát hiện ra rằng 'getpreferredencoding' [sử dụng] (https://github.com/python/cpython/blob/f7eae0adfcd4c50034281b2c69f461b43b68db84/Modules/_localemodule.c#L304) [GetACP] (https://msdn.microsoft.com/en-us/library/windows/desktop/dd318070(v=vs.85).aspx) Hàm WinAPI, nó "truy xuất mã nhận dạng trang ANSI của Windows hiện tại". – user

+0

Không có cơ chế trong Python để ghi đè hành vi này ngoại trừ việc sử dụng các hack phụ thuộc phiên bản giống như một gợi ý của Joran trong câu trả lời khác và những câu hỏi được tìm thấy trong câu trả lời cho [câu hỏi này] (https://stackoverflow.com/questions/ 31469707/change-the-locale-ưa thích-mã hóa-in-python-3-trong-windows). Từ những gì tôi đã đọc, cũng không có cơ chế để thiết lập mã hóa này thành UTF-8 trong Windows bên ngoài Python. Do đó, với thực tế là không có cách nào để thiết lập tùy chọn này mà không cần phải hack, tôi đồng ý rằng việc thay đổi điều này có thể không đáng tin cậy. Đã chấp nhận câu trả lời. – user

0

tôi sẽ không thay đổi bất cứ điều gì trong locale, vì nó có thể có rất nhiều tác dụng phụ trong các phần khác của hệ thống của bạn. open là một cuộc gọi hàm mức hệ thống, do đó, các thiết lập của nó có thể có các hiệu ứng bên ngoài đó, hoặc tại một chương trình Python tối thiểu khác sử dụng cùng một cài đặt Python. Wrapper của bạn trông phù hợp, rất sạch sẽ và di động, và có vẻ là giải pháp chính xác.

2

bạn có thể thiết lập mã hóa ... nhưng nó thực sự hacky

import sys 
sys.getdefaultencoding() #should print your default encoding 
sys.setdefaultencoding("utf8") #error ... no setdefaultencoding ... but... 
reload(sys) 
sys.setdefaultencoding("utf8") #now it succeeds ... 

tôi thay vào đó sẽ làm

main_script.py

import __builtin__ 
old_open = open 
def uopen(*args, **kwargs): 
    return open(*args, encoding='UTF-8', **kwargs) 
__builtin__.open = uopen 

sau đó bất cứ nơi nào bạn gọi open nó sẽ sử dụng mã hóa utf8 ... tuy nhiên, nó có thể cung cấp cho bạn các lỗi nếu bạn thêm mã hóa

012 một cách rõ ràng

hoặc chỉ rõ ràng vượt qua mã hóa bất cứ lúc nào bạn mở một tập tin, hoặc sử dụng wrapper của bạn ...

trăn triết lý chung là rõ ràng là tốt hơn so với tiềm ẩn, trong đó hàm ý "quyền" giải pháp là dứt khoát tuyên bố mã hóa của bạn khi mở một tệp ...

+0

Hack bằng mã hóa mặc định chỉ hoạt động trên Python 2. – user

+0

Tôi không chắc liệu có an toàn khi chỉ ghi đè hàm trong 'nội trang' vì điều đó cũng sửa đổi chức năng trong các mô-đun đã nhập hay không và một số thư viện có thể dựa vào giá trị mặc định. Tuy nhiên, nó có thể có ích trong một số trường hợp. Cảm ơn, +1 – user

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