Windows 上の Python FAQ¶
Python プログラムを Windows で動かすにはどうしますか?¶
これは必ずしも単純な質問ではありません。Windows コマンドラインからプログラムを実行するのに慣れてしまっている場合は、全て明らかなことに思えるでしょう; そうでない場合は、もう少し手引きが必要でしょう。
ある種の統合開発環境を使っているのでなければ、最終的には "コマンドプロンプト" などと呼ばれているものに、 Windows コマンドをタイプすることになるでしょう。
通常そういうウィンドウは検索バーで cmd を検索して起動します。
通常は次のような見た目の Windows の "コマンド プロンプト" が現れるので、ウィンドウが起動したのが分かるはずです:
C:\>
この文字は異なっていたり、続きがあったりするので、コンピュータの設定や、あなたが最近何をしたかに依って、このようになっていることもあるでしょう:
D:\YourName\Projects\Python>
このようなウィンドウさえ開けば、Python プログラムを動かす手順は順調に進みます。
Python スクリプトは Python インタプリタ と呼ばれる別のプログラムで処理されなければならないということを、理解する必要があります。インタプリタはスクリプトを読み込み、バイトコードにコンパイルし、バイトコードを実行しプログラムを走らせます。では、インタプリタが Python スクリプトを取り扱うためには、どんな用意をするのでしょうか?
まず最初に、コマンドウィンドウに "py" という単語がインタプリタを起動する指示であると認識させる必要があります。
コマンドウィンドウを開いたら、 py というコマンドを入力し、リターンキーを叩いてください。:
C:\Users\YourName> py
次のような出力が見えるでしょう:
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
インタプリタの"対話モード"が始まりました。これで Python の文や式を対話的に入力して、待っている間に実行や評価させることができます。これが Python の最強の機能のひとつです。いくつかの式を選んで入力し、結果を見て確かめてみましょう:
>>> print("Hello")
Hello
>>> "Hello" * 3
'HelloHelloHello'
多くの人が対話モードを便利で高度なプログラム可能計算機として使っています。対話式 Python セッションを終わらせたいなら、 exit() 関数を呼び出すか、 Ctrl キーを押しながら Z を入力し "Enter" キーを押して、 Windows コマンドプロンプトに戻ってください。
のような項目がスタートメニューに見付かるかもしれません。
これを起動すると、新しいウィンドウに >>> というプロンプトが見られるでしょう。その場合、 exit() 関数を呼び出すか Ctrl-Z を入力するとウィンドウは閉じます; Windows は 1 つの "python" コマンドをウィンドウで実行していて、インタプリタを終了させたときに、そのウィンドウを閉じます。
py コマンドが認識されていることが確認できたので、 Python スクリプトを与えられるようになりました。
そのためには Python スクリプトの絶対パスあるいは相対パスを与える必要があります。
Python スクリプトがデスクトップにあり、 hello.py という名前で、ちょうど良いことにコマンドプロンプトがホームディレクトリを開いていると仮定しましょう。
そうすると次のような表示が見られます:
C:\Users\YourName>
ここまで来れば py の後ろにスクリプトのパスを入力することで、 Python にスクリプトを渡すよう py コマンドに命令できます:
C:\Users\YourName> py Desktop\hello.py
hello
Python スクリプトを実行可能にするにはどうしますか?¶
Windows では、標準の Python インストーラはすでに .py 拡張子をあるファイル型 (Python.File) に関連付け、そのファイル型にインタプリタを実行するオープンコマンド (D:\Program Files\Python\python.exe "%1" %*) を与えます。コマンドプロンプトから 'foo.py' としてスクリプトを実行可能にするにはこれで十分です。スクリプトを拡張子なしで 'foo' とだけタイプして実行したいのなら、PATHEXT 環境変数に .py を加えてください。
Python の起動に時間がかかることがあるのはなぜですか?¶
通常 Python は Windows でとても早く起動しますが、ときどき Python が急にスタートアップに時間がかかるようになったというバグレポートがあります。更に複雑なことに、Python は同様に設定された他の Windows システムではきちんと動くのです。
問題が起きるマシンのウイルス対策ソフトウェアの設定が原因かもしれません。 ファイルシステムからの読み取りをすべて監視するように設定すると、起動時のオーバーヘッドが 100 倍程度になるウイルススキャナがあることが知られています。 各システムのウイルス対策ソフトウェアが本当に同じ設定になっているか確認してください。 特に McAfee は、ファイルシステムの読み取りをすべてスキャンする設定にすると、この問題を起こします。
どうすれば Python スクリプトを EXE に出来ますか?¶
実行可能ファイルを作れるツールの一覧 どうしたら Python スクリプトからスタンドアロンバイナリを作れますか? を参照してください。
*.pyd ファイルは DLL と同じですか?¶
はい、.pyd ファイルは DLL ですが、いくつか違いがあります。
foo.pyd という DLL には PyInit_foo() 関数が必要です。
Python で import foo と書くと、Python は foo.py や foo.pyc に加えて foo.pyd を探し、見つかれば PyInit_foo() を呼び出して初期化しようとします。
.exe を foo.lib にリンクする必要はありません。
リンクすると、Windows がその DLL の存在を必須とするようになるためです。
なお、foo.pyd を検索するパスは PYTHONPATH であり、Windows が foo.dll を検索するパスと同じではありません。また、プログラムを dll にリンクしたときはプログラムの実行に dll が必要ですが、foo.pyd は実行には必要はありません。もちろん、 import foo したいなら foo.pyd は必要です。DLL では、リンクはソースコード内で __declspec(dllexport) によって宣言されます。.pyd では、リンクは使える関数のリストで定義されます。
Python を Windows アプリケーションに埋め込むにはどうしたらいいですか?¶
Python インタプリタを Windows app に埋め込む方法は、次のように要約できます:
あなたの .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.libはpythonNN.dllに対するいわゆる "インポートライブラリ" です。これは単にリンカに対するシンボルを定義します。)実行時のリンクではすべての処理が実行時に行われるため、リンクオプションを大幅に簡略化できます。 コードでは Windows の
LoadLibraryEx()でpythonNN.dllを読み込む必要があります。 また、Windows のGetProcAddress()で得たポインタを使って、pythonNN.dll内のルーチンやデータ (Python の C API) にアクセスする必要があります。 マクロを使えば、Python の C API を呼び出す C コード側でこれらのポインタを意識せずに済むようにできます。SWIG を使えば、app のデータとメソッドを Python で使えるようにする Python "拡張モジュール"を簡単に作れます。SWIG は雑用を殆どやってくれるでしょう。結果として、.exe ファイル の中に リンクする C コードができます(!)。DLL を作 らなくてもよく、リンクも簡潔になります。
SWIG は拡張の名前に依る名前の init 関数 (C 関数) を作ります。例えば、モジュールの名前が leo なら、init 関数の名前は initleo() になります。SWIG shadow クラスを使ったほうがよく、そうすると init 関数の名前は initleoc() になります。これは shadow クラスが使うほとんど隠れた helper クラスを初期化します。
ステップ 2 の C コードを .exe ファイルにリンクできるのは、初期化関数の呼び出しと Python へのモジュールのインポートが同等だからです! (ドキュメント化されていない重大な事実の二つ目です)
要するに、以下のコードを使って Python インタプリタを拡張モジュール込みで初期化することができます。
#include <Python.h> ... Py_Initialize(); // Pythonの初期化 initmyAppc(); // ヘルパーclassの初期化(import) PyRun_SimpleString("import myApp"); // shadowクラスのimport
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 の
%typemapコマンドを使えば、この変更を自動化できるかもしれません。 ただし、私はこれを動作させられていません (SWIG についてはまったくの初心者です)。Python シェルスクリプトを使って Windows app 内から Python インタプリタウィンドウを掲示するのはいい方法ではありません。そのように表示されるウィンドウは app のウィンドウシステムとは関係ありません。むしろ "ネイティブな" インタプリタウィンドウを (wxPythonWindow を使ったりして) 作るべきです。そのウィンドウを Python インタプリタにつなぐのは簡単です。Python の i/o は読み書きをサポートする _どんな_ オブジェクトにもリダイレクトできるので、read() と write() メソッドを含む (拡張モジュールで定義された) Python オブジェクトさえあればいいのです。
エディタが Python ソースにタブを勝手に挿入しないようにするにはどうしますか?¶
この FAQ ではタブを使うことを勧めません。Python スタイルガイド PEP 8 では、配布される Python コードにはスペース 4 つを使うことを推奨しています。これは Emacs の python-mode のデフォルトでも同じです。
いかなるエディタでも、タブとスペースを混ぜるのは良くないです。 MSVC も全く同じ立場であり、スペースを使うようにする設定が簡単にできます。 を選択し、ファイルタイプの "デフォルト" の "タブ幅" と "インデント幅" に 4 を設定して、 "スペースを挿入する" のラジオボタンを選択してください。
Python は、もしタブとスペースが混在していることで先頭の空白に問題がある場合、IndentationError または TabError を送出します。
tabnanny モジュールを実行することで、ディレクトリーツリーをバッチモードでチェックすることができます。
ブロックすることなく押鍵を検出するにはどうしますか?¶
msvcrt モジュールを使ってください。
これは Windows 専用の標準拡張モジュールです。
キー入力があるかを調べる kbhit() と、入力された文字を表示せずに 1 文字取得する getch() が定義されています。
missing api-ms-win-crt-runtime-l1-1-0.dll エラーを解決するにはどうしますか?¶
この問題は更新がインストールされていない Windows 8.1 以前を使っていると Python 3.5 以降で発生することがあります。まずはあなたのオペレーティングシステムがサポートされており最新であることを確認してください。それでも解決しない場合は、 C ランタイムアップデートの手動インストール方法について Microsoft support page を参照してください。