http://docs.python.org/library/stdtypes.html#file.encoding
file.encoding
The encoding that this file uses. When Unicode strings are written to a file, they will be converted to byte strings using this encoding. In addition, when the file is connected to a terminal, the attribute gives the encoding that the terminal is likely to use (that information might be incorrect if the user has misconfigured the terminal). The attribute is read-only and may not be present on all file-like objects. It may also be None, in which case the file uses the system default encoding for converting Unicode strings.
これを見ると、 file.write(unicode_str) すると、 unicode_str は file.encoding に変換されて write されるように見える。だが、Windows で
>>> import sys >>> sys.stdout.encoding 'cp932' >>> u = u"あいう" >>> u u'\u3042\u3044\u3046' >>> print >>sys.stdout, u あいう >>> sys.stderr.write(u) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
実際、logging モジュールでも、
if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): #fs = fs.decode(stream.encoding) try: stream.write(fs % msg) except UnicodeEncodeError: #Printing to terminals sometimes fails. For example, #with an encoding of 'cp1251', the above write will #work if written to a stream opened or wrapped by #the codecs module, but fail when writing to a #terminal even when the codepage is set to cp1251. #An extra encoding step seems to be needed. stream.write((fs % msg).encode(stream.encoding)) else: ...
のように、file.encoding があるときは file.write(u) してみて、UnicodeEncodeErrorが発生したら file.write(u.encode(file.encoding)) している。
これは、 sys.stdout が file.encoding の convention に従っていないのだろうか?でも、printがencodeしてから出力しているところを見ると、fileにwriteする前にencodeするのは一般的な手続きなのだろうか?
今のところのfile.encodingのconventionは、fileにunicodeを書くときには encoding に変換されるが、変換するのが file.write() の内部なのか file.write() の外で変換してから write()に渡すべきなのかは決まっていない、というものに見える。
キモチワルすぎ。 py3k 早く来い。