Windows 上の Python FAQ

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

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

Unless you use some sort of integrated development environment, you will end up typing Windows commands into what is variously referred to as a "DOS window" or "Command prompt window". Usually you can create such a window from your Start menu; under Windows 7 the menu selection is Start ‣ Programs ‣ Accessories ‣ Command Prompt. You should be able to recognize when you have started such a window because you will see a Windows "command prompt", which usually looks like this:

C:\>

The letter may be different, and there might be other things after it, so you might just as easily see something like:

D:\YourName\Projects\Python>

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

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

First, you need to make sure that your command window recognises the word "python" as an instruction to start the interpreter. If you have opened a command window, you should try entering the command python and hitting return:

C:\Users\YourName> python

You should then see something like:

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

You have started the interpreter in "interactive mode". That means you can enter Python statements or expressions interactively and have them executed or evaluated while you wait. This is one of Python's strongest features. Check it by entering a few expressions of your choice and seeing the results:

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

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

スタート ‣ すべてのプログラム ‣ Python 3.5 ‣ 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:\Python33 などです。このコマンドで見つからなかった場合、ディスク全体から検索しなければならないでしょう ... Tools ‣ Find か、 Search ボタンを利用して、 "python.exe" を検索します。 Python が C:\Python33 (この文書を書いている時点のデフォルトです) にインストールされていたとして、次のコマンドで

c:\Python33\python

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

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

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 に出来ますか?

http://cx-freeze.sourceforge.net/ は、Python コードからコンソール、GUI の EXE を作れるようにする distutils の拡張です。 py2exe は最も有名な Python 2.x-ベースの EXE を作る拡張です。これは Python 3 をまだサポートしませんが、開発中です。

*.pyd ファイルは DLL と同じですか?

はい、.pyd ファイルは dll と同じようなものですが、少し違いがあります。foo.pyd という名前の DLL があったとしたら、それには関数 PyInit_foo() が含まれていなければなりません。そうすれば Python で "import foo" を書けて、Python は foo.pyd (や foo.py、foo.pyc) を探して、あれば、PyInit_foo() を呼び出して初期化しようとします。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 3.3 であれば "33" のような数字です。

    Python には、load-time に、または run-time にリンクできます。load-time なリンクは、 pythonNN.lib に対してリンクするもので、run-time なリンクは pythonNN.dll に対してリンクするものです。(一般的な注意: pythonNN.libpythonNN.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 を設定して、 "スペースを挿入する" のラジオボタンを選択してください。

Python は、もしタブとスペースが混在していることで先頭の空白に問題がある場合、IndentationError または TabError を送出します。 tabnanny モジュールを実行することで、ディレクトリーツリーをバッチモードでチェックすることができます。

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

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

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

Prior to Python 2.7 and 3.2, to terminate a process, you can use 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+CCtrl+Break をそれらのシグナルを扱うように設計されたコンソールのサブプロセスに送ることができます。

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

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

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