これでしれーっとやっちゃってるんだけれど。
これはまぁ「コードページを知るためのもの」ではないからね、そこでは触れなかったんだけれど、別件でまた必要になったついでに一応触れておこうかと。
まず、「公式 CPython Windows 版」の場合は、まぁこれで事足りるハズ:
1 Python 2.7.9 (default, Dec 10 2014, 12:28:03) [MSC v.1500 64 bit (AMD64)] on win32
2 Type "help", "copyright", "credits" or "license" for more information.
3 >>> import sys
4 >>> sys.getfilesystemencoding()
5 'mbcs'
「ファイルシステムエンコーディング」で事足りるの? 事足りるでしょう。システム内で一貫してるんだから。またこれは「コードページを知る」ことにはなってはいないけれど、問題ないわけである、「そうするニーズは実際にはない」んだから。つまり「いつでも mbcs を必要な場合に encode、decode に渡せる」のだから。
同じ Windows でも「cygwin 版 CPython」「msys2 版 CPython」では事情が違ってくる。msys2 版も cygwin 版もこうなる:
1 Python 2.7.13 (default, Feb 14 2017, 14:46:01)
2 [GCC 6.3.0] on msys
3 Type "help", "copyright", "credits" or "license" for more information.
4 >>> import sys
5 >>> sys.getfilesystemencoding()
6 'UTF-8'
行儀悪いったらないと思う。「郷に入っても郷に従うものか」、とオレ流をあくまで貫こうとする。もちろん普通の Windows アプリケーションを主食にしてれば当然そう思うけれど、msys2 も cygwin も「自分は unix だ」と思い込んでいたいわけだし、この中のアプリケーションにとっては「それこそがありがたいこと」だったりもするわけで、痛し痒し、としか言いようがない。
実際はもう一つある。「じゃぁ固定値で mbcs 使っちゃえばいいじゃん」が、msys2、cygwin には通用しない。なぜなら「mbcs は Windows 版固有のコーデック」なので、「unix だと思い込んでいる cygwin、msys2」には適用されない。つまり mbcs を使えない。代わりに「cpNNN」(日本語版 Windows なら cp932) は使える。ゆえ、どうにかしてこの「cpNNN」を知る必要がある。そう、ここでやっと「コードページを知る必要がある」。
これへの「msys2/cygwin ワールドにクローズドな解」はない。ゆえ、「恐怖の DOS コマンド」に頼らなければならない:
1 from __future__ import unicode_literals
2
3 import os
4 import sys
5 import re
6 import subprocess
7
8
9 if sys.platform in ("win32", "msys", "cygwin"):
10 _ENCODING_IN = "mbcs"
11 if sys.platform in ("msys", "cygwin"):
12 # msys2 and cygwin don't have mbcs codec,
13 # but they have "cp*", so try to detect
14 # codepage of your windows.
15 _dosmes = os.environ["COMSPEC"].replace("\\", "/") # cmd.exe
16 _chcp = subprocess.check_output(
17 [_dosmes, "/c", "chcp"]).decode("quopri")
18 # ↑日本語版 Windows だとバリバリ日本語で返ってくる、ので quopri
19 _ENCODING_IN = "cp" + re.match(r".*: (\d+)$", _chcp.strip()).group(1)
subprocess が「Windows native のバックスラッシュ区切り」を頑なに拒絶し、かつ、「os.sep」を使えない(だって「/」だもん)てところも絶妙に鬱陶しかったりもするが、ともあれここまでやってようやく「cp932」を得られる。