今までの方法をよく考えると、わざわざクラスを作る必要は無かった。クラスを無くして、少しだけ簡略化した。
def get_text_writer(fileno, **kwargs): kw = dict(kwargs) kw.setdefault('errors', 'backslashreplace') kw.setdefault('closefd', False) writer = io.open(fileno, mode='w', **kw) # work around for Python 2.x write = writer.write # save the original write() function enc = locale.getpreferredencoding() writer.write = lambda s: write(s.decode(enc)) \ if isinstance(s, bytes) else write(s) # convert to unistr return writer sys.stdout = get_text_writer(sys.stdout.fileno(), encoding=outenc) sys.stderr = get_text_writer(sys.stderr.fileno(), encoding=outenc)
Python 2.x/3.x 共通の方法で標準出力のエンコーディングを設定する方法の見直しを行った。以前の方法だと、システムが出すエラーメッセージに日本語が含まれていたりすると、エラー出力が正しく表示されなかったので、Unicode 文字列への変換をもう少しまともに処理するようにしてみた。
class TextWriter: def __init__(self, fileno, **kwargs): kw = dict(kwargs) kw.setdefault('errors', 'backslashreplace') kw.setdefault('closefd', False) self._writer = io.open(fileno, mode='w', **kw) # work around for Python 2.x _write = self._writer.write # save the original write() function enc = locale.getpreferredencoding() self._writer.write = lambda s: _write(s.decode(enc)) \ if isinstance(s, bytes) else _write(s) # convert to unistr def getwriter(self): return self._writer sys.stdout = TextWriter(sys.stdout.fileno(), encoding=outenc).getwriter() sys.stderr = TextWriter(sys.stderr.fileno(), encoding=outenc).getwriter()
相変わらず無駄に長いのが難点である。もう少しコンパクトにしたい。