# Windows 上の Python FAQ

目次

- Windows 上の Python FAQ

  - Python プログラムを Windows で動かすにはどうしますか？

  - Python スクリプトを実行可能にするにはどうしますか？

  - Python の起動に時間がかかることがあるのはなぜですか？

  - どうすれば Python スクリプトを EXE に出来ますか?

  - `*.pyd` ファイルは DLL と同じですか？

  - Python を Windows アプリケーションに埋め込むにはどうしたらいいですか？

  - エディタが Python ソースにタブを勝手に挿入しないようにするにはどうしますか？

  - ブロックすることなく押鍵を検出するにはどうしますか？

  - os.kill() を Windows で模倣するにはどうしますか？

  - ダウンロードされたドキュメントを Windows 上で展開するにはどうしますか？

## Python プログラムを Windows で動かすにはどうしますか？

これは必ずしも単純な質問ではありません。Windows コマンドラインからプログラムを実行するのに慣れてしまっている場合は、全て明らかなことに思えるでしょう; そうでない場合は、もう少し手引きが必要でしょう。

ある種の統合開発環境を使っているのでなければ、最終的には "DOS ウィンドウ" や "コマンドプロンプト" などと色々に呼ばれているものに、 Windows コマンドをタイプすることになるでしょう。通常そういうウィンドウはスタートメニューから起動します; Windows 7 では、 スタート ‣ すべてのプログラム ‣ アクセサリ ‣ コマンドプロンプト とメニューを選択します。通常は次のように見える Windows の "コマンド プロンプト" が現れるので、ウィンドウが起動したのが分かるはずです:

    C:\>

この文字は異なっていたり、続きがあったりするので、コンピュータの設定や、あなたが最近何をしたかに依って、このようになっていることもあるでしょう:

    D:\YourName\Projects\Python>

このようなウィンドウさえ開けば、Python プログラムを動かす手順は順調に進みます。

Python スクリプトは Python インタプリタ と呼ばれる別のプログラムで処理されなければならないということを、理解する必要があります。インタプリタはスクリプトを読み込み、バイトコードにコンパイルし、バイトコードを実行しプログラムを走らせます。では、インタプリタが Python スクリプトを取り扱うためには、どんな用意をするのでしょうか?

まず最初に、コマンドウィンドウに "python" という単語がインタプリタを起動する指示であると認識させる必要があります。コマンドウィンドウを開いたら、`python` というコマンドを入力し、リターンキーを叩いてください。:

    C:\Users\YourName> python

次のような出力が見えるでしょう:

    Python 2.7.3 (default, Apr 10 2012, 22.71:26) [MSC v.1500 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>>

インタプリタの"対話モード"が始まりました。これで Python の文や式を対話的に入力して、待っている間に実行や評価させることができます。これが Python の最強の機能のひとつです。いくつかの式を選んで入力し、結果を見て確かめてみましょう:

    >>> print "Hello"
    Hello
    >>> "Hello" * 3
    'HelloHelloHello'

多くの人が対話モードを便利で高度なプログラム可能計算機として使っています。対話式 Python セッションを終わらせたいなら、 `Ctrl` キーを押しながら `Z` を入力し、 "`Enter`" キーを打って Windows コマンドプロンプトに戻ってください。

スタート ‣ すべてのプログラム ‣ Python 2.7 ‣ Python (command line) という項目がスタートメニューにあるのに気付くかもしれません。これを起動すると、新しいウィンドウに `>>>` というプロンプトが見られるでしょう。そうなった場合、 `Ctrl-Z` を入力するとウィンドウは閉じます; Windows は 1 つの "python" コマンドをウィンドウで実行していて、インタプリタを終了させたときに、それを閉じます。

`python` コマンドで、インタプリタプロンプト `>>>` ではなく次のようなメッセージ:

    'python' is not recognized as an internal or external command, operable program or batch file.

もしくは:

    Bad command or filename

が現れたなら、コンピュータが Python インタプリタの場所を認識しているか確かめなければなりません。そのためには、Windows がプログラムを探すディレクトリのリストである PATH という設定を変更しなければなりません。

コマンドウィンドウが始まるごとに Python がインストールされたディレクトリが PATH に加えられるように設定するといいでしょう。あなたが Python をインストールしたのが結構最近なら、コマンド

    dir C:\py*

で、多分どこにインストールされたかがわかります。一般的な場所は `C:\Python27` などです。このコマンドで見つからなかった場合、ディスク全体から検索しなければならないでしょう ... Tools ‣ Find か、 Search ボタンを利用して、 "python.exe" を検索します。 Python が `C:\Python27` (この文書を書いている時点のデフォルトです) にインストールされていたとして、次のコマンドで

    c:\Python27\python

上にあるようにインタプリタが起動することを確認する必要があります。("`Ctrl-Z`" と "`Enter`" でインタプリタから抜けることも忘れないで下さい。) Python がインストールされたディレクトリを確認したら、`python` コマンドだけで Python を起動できるようにシステム・パスにそのディレクトリを追加しておくと良いでしょう。CPython 2.7 からはインストーラーのオプションでパスの追加ができるようになりました。

環境変数についてのさらなる情報は 補足: 環境変数の設定 に書かれています。

## Python スクリプトを実行可能にするにはどうしますか？

Windows では、標準の Python インストーラはすでに .py 拡張子をあるファイル型 (Python.File) に関連付け、そのファイル型にインタプリタを実行するオープンコマンド (`D:\Program Files\Python\python.exe "%1" %*`) を与えます。コマンドプロンプトから 'foo.py' としてスクリプトを実行可能にするにはこれで十分です。スクリプトを拡張子なしで 'foo' とだけタイプして実行したいのなら、PATHEXT 環境変数に .py を加えてください。

## Python の起動に時間がかかることがあるのはなぜですか？

通常 Python は Windows でとても早く起動しますが、ときどき Python が急にスタートアップに時間がかかるようになったというバグレポートがあります。更に複雑なことに、Python は同様に設定された他の Windows システムではきちんと動くのです。

この問題はそのマシンのウイルス対策ソフトウェアの設定ミスによって起こされることがあります。ウイルススキャナの中には、ファイルシステムからの全ての読み込みを監視するように設定した場合に、二桁のスタートアップオーバーヘッドを引き起すことが知られているものがあります。あなたのシステムのウイルススキャンソフトウェアの設定を確かめて、本当に同様に設定されていることを確実にしてください。

## どうすれば Python スクリプトを EXE に出来ますか?

Python コードからコンソールとGUI の実行可能形式を作るための distutils 拡張が http://www.py2exe.org/ にあります。

## `*.pyd` ファイルは DLL と同じですか？

はい、.pyd ファイルは dll と同じようなものですが、少し違いがあります。 `foo.pyd` という名前の DLL があったとしたら、それには関数 `initfoo()` が含まれていなければなりません。そうすれば Python で "import foo" を書けて、 Python は foo.pyd (や foo.py、foo.pyc) を探して、あれば、 `initfoo()` を呼び出して初期化しようとします。Windows が DLL の存在を必要とするのと違い、 .exe ファイルを foo.lib にリンクするわけではありません。

なお、foo.pyd を検索するパスは PYTHONPATH であり、Windows が foo.dll を検索するパスと同じではありません。また、プログラムを dll にリンクしたときはプログラムの実行に dll が必要ですが、foo.pyd は実行には必要はありません。もちろん、 `import foo` したいなら foo.pyd は必要です。DLL では、リンクはソースコード内で `__declspec(dllexport)` によって宣言されます。.pyd では、リンクは使える関数のリストで定義されます。

## Python を Windows アプリケーションに埋め込むにはどうしたらいいですか？

Python インタプリタを Windows app に埋め込む方法は、次のように要約できます:

1. あなたの .exe 内に直接 Python を取り込んでビルド しないで 下さい。Windows では、それ自身が DLL になっているようなモジュールのインポートを処理するために、Python は DLL でなければなりません。(これは最初の鍵で、ドキュメントされていない事実です。)代わりに、 `pythonNN.dll` とリンクしてください; 普通はそれは `C:\Windows\System` にインストールされています。 NN は Python バージョンで Python 2.7 であれば "27" のような数字です。

   Python には、load-time に、または run-time にリンクできます。load-time なリンクは、 `pythonNN.lib` に対してリンクするもので、run-time なリンクは `pythonNN.dll` に対してリンクするものです。(一般的な注意: `pythonNN.lib` は `pythonNN.dll` に対するいわゆる "インポートライブラリ" です。これは単にリンカに対するシンボルを定義します。)

   run-time なリンクは、リンクの選択を大いに単純化します。全ては実行時に行われます。コードは Windows の `LoadLibraryEx()` ルーチンで `pythonNN.dll` をロードしなければなりません。コードはまた、Windows の `GetProcAddress()` ルーチンで得られるポインタで、 `pythonNN.dll` (すなわち、Python の C API)のルーチンとデータへアクセスしていなければなりません。マクロによって、このポインタを Python の C API のルーチンを呼び出す任意の C コードに通して使えます。

   Borland note: まず `pythonNN.lib` を Coff2Omf.exe で OMF フォーマットに変換してください。

2. SWIG を使えば、app のデータとメソッドを Python で使えるようにする Python "拡張モジュール"を簡単に作れます。SWIG は雑用を殆どやってくれるでしょう。結果として、.exe ファイル の中に リンクする C コードができます(！)。DLL を作 _らなくてもよく_、リンクも簡潔になります。

3. SWIG は拡張の名前に依る名前の init 関数 (C 関数) を作ります。例えば、モジュールの名前が leo なら、init 関数の名前は initleo() になります。SWIG shadow クラスを使ったほうがよく、そうすると init 関数の名前は initleoc() になります。これは shadow クラスが使うほとんど隠れた helper クラスを初期化します。

   ステップ 2 の C コードを .exe ファイルにリンクできるのは、初期化関数の呼び出しと Python へのモジュールのインポートが同等だからです！ (ドキュメント化されていない重大な事実の二つ目です)

4. 要するに、以下のコードを使って Python インタプリタを拡張モジュール込みで初期化することができます。

       #include "python.h"
       ...
       Py_Initialize();  // Initialize Python.
       initmyAppc();  // Initialize (import) the helper class.
       PyRun_SimpleString("import myApp");  // Import the shadow class.

5. Python の C API には、pythonNN.dll をビルドするのに使われたコンパイラ MSVC 以外のコンパイラを使うと現れる二つの問題があります。

   問題 1: コンパイラによって struct FILE に対する概念が異なるため、FILE * 引数を取るいわゆる "超高水準" 関数は、多コンパイラ環境で働きません。実装の観点から、これらは超 _低_ 水準関数になっています。

   問題 2: SWIG は void 関数へのラッパを生成するときに以下のコードを生成します:

       Py_INCREF(Py_None);
       _resultobj = Py_None;
       return _resultobj;

   ああ、Py_none は pythonNN.dll 内の _Py_NoneStruct という複雑なデータ構造に展開するマクロです。また、このコードは他コンパイラ環境では失敗します。このコードを次のように置き換えてください:

       return Py_BuildValue("");

   これで、SWIG をまだ仕事に使えない (私は SWIG の完全な初心者です) 私でも、SWIG の `%typemap` コマンドを使って自動的に変更できるようになります。

6. Python シェルスクリプトを使って Windows app 内から Python インタプリタウィンドウを掲示するのはいい方法ではありません。そのように表示されるウィンドウは app のウィンドウシステムとは関係ありません。むしろ "ネイティブな" インタプリタウィンドウを (wxPythonWindow を使ったりして) 作るべきです。そのウィンドウを Python インタプリタにつなぐのは簡単です。Python の i/o は読み書きをサポートする _どんな_ オブジェクトにもリダイレクトできるので、read() と write() メソッドを含む (拡張モジュールで定義された) Python オブジェクトさえあればいいのです。

## エディタが Python ソースにタブを勝手に挿入しないようにするにはどうしますか？

この FAQ ではタブを使うことを勧めません。Python スタイルガイド PEP 8 では、配布される Python コードにはスペース 4 つを使うことを推奨しています。これは Emacs の python-mode のデフォルトでも同じです。

いかなるエディタでも、タブとスペースを混ぜるのは良くないです。 MSVC も全く同じ立場であり、スペースを使うようにする設定が簡単にできます。 Tools ‣ Options ‣ Tabs を選択し、ファイルタイプの "デフォルト" の "タブ幅" と "インデント幅" に 4 を設定して、 "スペースを挿入する" のラジオボタンを選択してください。

If you suspect mixed tabs and spaces are causing problems in leading whitespace, run Python with the `-t` switch or run the `tabnanny` module to check a directory tree in batch mode.

## ブロックすることなく押鍵を検出するにはどうしますか？

msvcrt モジュールを使ってください。これは標準の Windows 専用拡張モジュールです。これはキーボードが打たれているかを調べる関数 `kbhit()` と、反響することなく一文字を得る `getch()` を定義します。

## os.kill() を Windows で模倣するにはどうしますか？

Python 2.7 および 3.2 以前では、プロセスを終了するために、 `ctypes` が使えます:

    import ctypes

    def kill(pid):
        """kill function for Win32"""
        kernel32 = ctypes.windll.kernel32
        handle = kernel32.OpenProcess(1, 0, pid)
        return (0 != kernel32.TerminateProcess(handle, 0))

2.7 および 3.2 では、上の関数と同様な `os.kill()` が実装されていて、追加の機能として、 `Ctrl+C` や `Ctrl+Break` をそれらのシグナルを扱うように設計されたコンソールのサブプロセスに送ることができます。

## ダウンロードされたドキュメントを Windows 上で展開するにはどうしますか？

たまに、web ブラウザで Windows マシンにドキュメントパッケージをダウンロードするとき、その保存されたファイルの拡張子が .EXE になっていることがあります。これは間違いです。本来の拡張子は .TGZ です。

単純に、ダウンロードしたファイルを名付け直して拡張子を .TGZ にしてください。そうすれば WinZip で扱えます。(手元の WinZip でできなかったら、https://www.winzip.com から新しいのをもらいましょう)