Windows 上の Python FAQ
***********************


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 でなければなりません。(こ
   れは最 初の鍵で、ドキュメントされていない事実です。)代わりに、
   "python*NN*.dll" とリンクしてください; 普通はそれは
   "C:\Windows\System" にインストールされています。 *NN* は Python バ
   ージョンで Python 2.7 であれば "27" のような数字です。

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

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

   Borland note: まず "python*NN*.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 から新しいのをもらいましょう)
