Đầu tiên: reload(sys)
và thiết lập một số mã hóa mặc định ngẫu nhiên chỉ liên quan đến nhu cầu của một luồng đầu cuối đầu ra là thực tế xấu. reload
thường thay đổi mọi thứ trong các hệ thống đã được đặt đúng chỗ tùy thuộc vào môi trường - ví dụ: các luồng sys.stdin / stdout, sys.ex805thook, v.v.
Giải quyết vấn đề mã hóa trên thiết bị xuất chuẩn
Giải pháp tốt nhất mà tôi biết để giải quyết vấn đề mã hóa của print
'chuỗi unicode và ngoài chuỗi ascii str
(ví dụ từ chữ) trên sys.stdout là: chăm sóc một sys.stdout (đối tượng giống như tệp) có khả năng và tùy chọn khoan dung liên quan đến nhu cầu:
Khi sys.stdout.encoding
là None
đối với một số lý do nào, hoặc không tồn tại, hoặc sai lầm sai hay "ít" so với những gì nhà ga stdout hoặc dòng thực sự có khả năng, sau đó cố gắng cung cấp một đúng .encoding
thuộc tính. Cuối cùng bằng cách thay thế sys.stdout & sys.stderr
bằng một đối tượng giống như tập tin dịch.
Khi thiết bị đầu cuối / luồng vẫn không thể mã hóa tất cả các ký tự unicode xảy ra và khi bạn không muốn phá vỡ print
chỉ vì điều đó, bạn có thể đưa ra một hành vi mã hóa thay thế trong đối tượng giống như tệp dịch.
Dưới đây là một ví dụ:
#!/usr/bin/env python
# encoding: utf-8
import sys
class SmartStdout:
def __init__(self, encoding=None, org_stdout=None):
if org_stdout is None:
org_stdout = getattr(sys.stdout, 'org_stdout', sys.stdout)
self.org_stdout = org_stdout
self.encoding = encoding or \
getattr(org_stdout, 'encoding', None) or 'utf-8'
def write(self, s):
self.org_stdout.write(s.encode(self.encoding, 'backslashreplace'))
def __getattr__(self, name):
return getattr(self.org_stdout, name)
if __name__ == '__main__':
if sys.stdout.isatty():
sys.stdout = sys.stderr = SmartStdout()
us = u'aouäöüфżß²'
print us
sys.stdout.flush()
Sử dụng các chuỗi ký tự đơn giản ngoài chuỗi ascii trong mã Python 2/2 + 3
Lý do chính đáng duy nhất để thay đổi mã hóa mặc định toàn cầu (chỉ thành UTF-8) Tôi nghĩ là liên quan đến quyết định mã nguồn ứng dụng - và không phải do vấn đề mã hóa luồng I / O: Để viết các chuỗi ký tự ngoài chuỗi ascii thành mã mà không bị ép buộc để luôn luôn sử dụng u'string'
kiểu unicode thoát. Điều này có thể được thực hiện khá nhất quán (mặc dù bài báo của anonbadger nói) bằng cách chăm sóc cơ sở mã nguồn Python 2 hoặc Python 2 + 3 sử dụng các chuỗi ký tự đơn giản ascii hoặc UTF-8 - theo như các chuỗi đó có khả năng im lặng chuyển đổi unicode và di chuyển giữa các mô-đun hoặc có khả năng đi đến thiết bị xuất chuẩn. Cho rằng, thích "# encoding: utf-8
"Hoặc ascii (không khai báo). Thay đổi hoặc loại bỏ các thư viện vẫn phụ thuộc rất nhiều vào các lỗi mã hóa mặc định của ascii ngoài chr # 127 (ngày nay rất hiếm).
Và làm như thế này khi bắt đầu ứng dụng (và / hoặc thông qua sitecustomize.py) ngoài SmartStdout
sơ đồ trên - mà không cần sử dụng reload(sys)
:
...
def set_defaultencoding_globally(encoding='utf-8'):
assert sys.getdefaultencoding() in ('ascii', 'mbcs', encoding)
import imp
_sys_org = imp.load_dynamic('_sys_org', 'sys')
_sys_org.setdefaultencoding(encoding)
if __name__ == '__main__':
sys.stdout = sys.stderr = SmartStdout()
set_defaultencoding_globally('utf-8')
s = 'aouäöüфżß²'
print s
Bằng cách này, chuỗi ký tự và hầu hết các hoạt động (ngoại trừ lặp ký tự) hoạt động thoải mái mà không cần suy nghĩ về chuyển đổi unicode như thể chỉ có Python3. Tất nhiên, tệp I / O luôn cần được chăm sóc đặc biệt về mã hóa - như trong Python3.
Lưu ý: chuỗi đồng bằng sau đó được chuyển đổi hoàn toàn từ utf-8 sang unicode SmartStdout
trước khi được chuyển đổi sang luồng đầu ra.