PythonでCOMの引数に配列を指定する2014年11月01日 11:58

この記事は、10月22日の「Perl,Ruby,PythonでCOMの引数に配列を指定する」の続きです。

「受け取るためだけの引数なら戻り値にしてしまうという発想は、自由で面白い」などと書きましたが、実は Perl、Ruby と同じようなものだろうと思って試行錯誤しているうちに偶然発見したことです。本来は、試行錯誤する破目になったなら、'makepy'というユーティリティを使って、COMのタイプライブラリからインタフェースとなるPythonコードを生成するのが真っ当なやり方です。
念のため、あのやり方で正しいのだということを、インタフェースを見て確認することにしました。
早速、'makepy'でインタフェースとなるPythonコードを生成します。と言いたいところですが、その必要はありませんでした。Dispatchした段階で、Dispatchしたクラスの部分だけですが動的にインタフェースが生成されていました。生成された場所は、C:\Users\[USERNAME]\AppData\Local\Temp\gen_py\3.4\[IID]\ です。
Names.py,INames.pyの内、インタフェースであるINames.pyのAllNamesメソッドを眺めると、何やら難しそうですが、引数の配列は 'Codes=pythoncom.Missing, Names=pythoncom.Missing'になっています。そして戻り値の記述に ', Codes, Names)' が入っています。
やはり、あのやり方で正しいのでした。

せっかくだから、'makepy'もやってみます。
私はC:\Python34にPythonをインストールしているので、c:\Python34\Lib\site-packages\win32com\client\makepy.pyを起動すると、タイプライブラリを選択するウインドウが表示される……ハズなのですが、
ImportError: No system module 'pywintypes' (pywintypes34.dll)
になりました。(これは、pywin32-Build218 での現象です。Build219 では正常に起動しました。)
そこで、次のような簡単なスクリプト経由で起動することにしました。
1 from win32com.client import makepy
2 makepy.main()

無事にタイプライブラリの選択画面が表示されました。お目当てのタイプライブラリを選んで「OK」をクリック。
c:\Python34\Lib\site-packages\win32com\client>python gomakepy.py
Generating to C:\Users\foo\AppData\Local\Temp\gen_py\3.4\02EC46E1-E40A-11D1
-A405-0080C88597E5x0x1x3.py
Building definitions from type library...
Generating...
Importing module

c:\Python34\Lib\site-packages\win32com\client>

今度は、C:\Users\[USERNAME]\AppData\Local\Temp\gen_py\3.4\ 直下に生成されました。勿論、Namesクラスだけでなくすべてのクラス、メソッドのインタフェースです。

それでは、
nm = win32com.client.Dispatch("ActiveMarket.Names.1") --> dynamic dispatch
nm = win32com.client.gencache.EnsureDispatch("ActiveMarket.Names.1") --> static dispatch
の違いも調べてみます。
\gen_py\3.4\ 以下のファイルを削除してはそれぞれの dispatch を実行して、生成されたファイルとその更新時間を見るという単純なやり方です。
  • dynamic dispatch
    • 'makepy'で生成したものがあれば、それを使う。
    • なければ、動的に生成する。(既に動的に生成されたものがあれば、新たに生成しない。)
  • static dispatch
    • 'makepy'で生成したものがあれば、それを使う。
    • なければ、'dynamic'と同じものを動的に生成する。(既に動的に生成されたものがあれば、新たに生成しない。)
インタフェースの生成に関してはまったく同じ動作のように見えますが、何か別の意味で深遠な違いがあるのかもしれません。