Hope is a Dream. Dream is a Hope.

非公開ブログは再開しました。

Windows .NET C#からPythonを使う。2017年3月30日版。

Windows .NET C#からPythonを使う。2017年3月30日版。

現在2017年3月30日

日頃Pythonを使って開発をしている。

最近の流行では、機械学習やその他便利な処理などをWindows環境でやっている。モチロンAnacondaを使ってだ。例えば、Numpy, Scipyを使って音声処理をしたり、OpenCVヲ使って画像処理をしたり。たまには、BeautifulSoupを使ってWebをスクレイピングしている。モチロン黒い画面が主だ。適当な設定条件で、適当な入力を指定し、適当な形式の結果を受ける。結果はグラフであったり、音声・画像、またはCSVだ。それら大事な結果を、上手くフォーマットし、openpyxl等でエクセルやパワポへ貼り付け、上司へ提出するだろう。ほとんどはテキストエディタと黒い画面がデスクトップ上で動き回る。ボタン一つで上司への成果がでるのはとても気持ちいものだ。

黒い画面以外にもPythonは良いツールとなる。

最近の流行では、PySideは止めPyQt5を使ってGUIを構築する。機械学習で障害物を避けるシミュレーションを描いたり、音声や画像をリアルタイムで表示する。ときには、処理の遅さにがっかりしそうになるが、上司への報告書の作成では、自作のスクリプト達の働きに頭が上がらないので、ぐっとこらえる。決して「Python遅すぎワロタ」なんて口にしない。PyQtデザイナーを使い、GUI上でレイアウトを定め、基本のシグナルスロットはGUIでつなげる。途中にコンバーターをはさむ。作ってくれた人ありがとう。Kivyも良い。使わないがクロスプラットフォームだし、デフォルトのスタイルが黒ベースでカッコイイ。やはりGUIは良い。直感的にアルゴリズムの動作を確認できる。黒い画面で設定を変えて何度もトライし結果を比較するのとは、また違う見方ができる。一人集中して視野が狭くなっているときには、難しいことは考えずにポチポチクリックしながら結果を眺めるのは良い成果に繋がることもある。そして、上司や同僚にGUIで説明する機会が増えてくる。そうすると、PythonだってWindowsのソフトウェアみたいにexe化したり、配布したくなる。インタプリタ言語だから少々背伸びしているのは分かっている。

でも、Pythonは世界中の凄腕ハッカー達が使っている成熟した言語だ。ファンも沢山いる。プログラム言語ならexe化できるだろう。そう。できる。PyInstallerやpy2exeを使えば、その名の通り、Windowsのソフトウェアみたいになれる。でも、ちょっとテクニックやノウハウは必要だ。Pythonをexeにしてもそれは、「exe風に使える」だけであって(黒い画面を立ち上げなくて良い)、あこがれるWindowsネイティブとは異なる。exeの中には僕らのpythonが入っていて、ダブルクリックの後に、見えないところで黒い画面が動いているのだ。クリックするとGUIが開く点では同じ。ならexe化すればWindowsアプリ風に振舞うのであればPythonは最強じゃないか。と思うが、exe化にはノウハウが必要。exe化しても裏ではpythonが黒い画面で動いている。まずは32Bitか64Bitかも考えよう。きみはもう64bitを使っているかな。機械学習やらGPUやらで遊んでいるなら64bit版のpythonかもしれない。モチロン64bit版Pythonでは32bitのwindowsPCでは動かない。裏では黒い画面じょうでpythonが動いているのだから。いくつも環境を用意してexe化してあげればいいから大きな問題にはならないが。次はモジュールだ。君が基本モジュールだけでアプリを作ったなら全然問題にはならない。でもそれだと黒い画面でやるのと変わらないかも。GUIは基本モジュールだけはできなからね(Tkinterは置いておいて)。カッコイイGUIPyQtで作っていると、なかなかexe化できないことがおきる。

たまにね。exe化のときにimportしているモジュールを全部一箇所に集めるんだ。隣の同僚のPCには入っていないかもしれないからね。モジュールは普通site-packageなんちゃらに沢山入っている。そこのパスを探していろいろ集めてくるんだけど、それがたまに上手くいかないことがある。Matplotlibも注意が必要かも。アルゴリズムを動かすGUIを作って、Matplotlibで描いたグラフを出力できると楽だよね。コード量も少ないし。でもMatplotlibはエラーと相性が良いから、exe化するときはいつも緊張するよね。大抵はパスを教えてあげると良かったりする。あと、リソースともいろいろお作法があるから気お付けて、たまに使うと忘れちゃうからどっかにメモると良いね。

昨日、僕の自信作のアルゴリズムで画像に修正を加えるデモをGUIを使って披露しようとウキウキしてた。焦ったのは前日のexe化の時に突然エラーがでて、冷や汗かいたけどなんとかexe化できた。数百MBぐらい。これはWindowsネイティブをしている人からすると、その規模では大きすぎ・・感じらしい。まぁ中にPythonを隠しているから仕方ないよね。pyqtもmplも大きいし。まぁ良いさその分pythonの恩恵を受けているし。そして、同僚のPCに送って披露の準備はできた。みんなを集めて、デスクトップ上にある、てんとう虫のオリジナルアイコンをダブルクリックした。すぐには開かない。裏では一度pythonを広げてモジュールも広げて、せっせといつもの環境を作ろうとしてるからさ。そんなの承知だ、まぁみんなちょっと待ってね。これPythonだから。それから何分立っただろう。待ち遠しいからプレゼンのスライドに戻っていろいろ説明していたらやっと立ち上がった。ほんとに長かった。そして立ち上がったのはアルゴリズムの説明するための簡単なアプリだ。Adobeの重たいソフトでもこんなにかからないのに。そして簡単なデモをして僕のpythonアプリの仕事は終わった。ちょっとどこか悲しかった。

そして上司から次のデモはWindowsアプリが良いんじゃないかといわれた。デモGUIまでもPythonでと思っていたが。心のどこかで諦めがついた。

僕は初めてVisual Studioを入れた。インストールに時間がかかった。こんなに時間がかかるなんてPythonならすぐなのにとちょっと寂しい気持ちになった。IDEは色々詰まっていた。言語はC言語家系のC++C#が選べる。それと.NETフレームワークを使うらしい。.NETってのはWindowsを普通に使っていると良く見かけている。いざそれか。GUIを作るには、Windows Formアプリと、MFCアプリってのがある。どっちが良いのか分からないけど、昔からあるのはFormの方で、MFCってのはちょっと若いらしい。MVVMらしい。C++は昔触ったことがあったので、C++でFormアプリを選らんでサンプルをまわした。なんと無く動いた。ヘッダファイル(.h)が煩わしい涙。型や引数が大文字だったりしてプログラムが入ってこない。pythonなら変数はスネークケースにしようとか、変数名はあまり短くしないで可読性高めようって意識に比べると、暗号にみえた。ちょっと挫折。上司にC#でやってみたらと進められた。C#オブジェクト指向で比較的新しいからPythonしか分からない僕にはいいかもって。実はC++は完全なオブジェクト指向でもないらしい。

C#に出会った。C#でもFormアプリケーションを作れるらしい。ちなみにVBでもできるらしい。.NETってのをいろんな言語で動かしてるのがWindowsアプリケーションなのかと、良く分からないながら想像する。でも、先週よりはWindowsが近くなった。そして、Formアプリケーションのサンプルをまわしてみる。ボタンを置いて、コールバック関数が作られて、そのなかにハローワールドをおく。ボタンを押すと見慣れたメッセージボックスがでてくる。モチロン毎回コンパイルされているので、プロジェクトディレクトリを見るとそには「exe」ファイルがある。ファイルを開くサンプルをまわしてみる。openFileDialogっていうやつをマウスで乗せる。そして、先ほどのボタンのコールバックに、ダイアログ開くをしてあげる。ボタンを押すと見慣れた画面でファイルを選べる。するとexeが出ている。exeの実体がどこで、実行ディレクトリがどこでどうのなんてエラーはなかった。なにも苦労もせずにメールで送れるファイルサイズのexeができてる。同僚に送ってみると。モチロン動く。動き出すのも一瞬。ちょっとWindowsアプリの事が分かった。VisualStudioの事が少し好きになった。

VisualStudioもとても使いやすいIDEだった。コードの予測は高速だし。コードドキュメントがいたるところで出てくる。しかも日本語で。マイクロソフトへの偏見が一つ消えた。一週間が終わるころにはVSのGUIデザインがかっこよく見えるようになった。

愛着が湧いたのでアイコンを変えてみようと思った。「.NET form アイコン」でググると、親切な記事が山ほどでてきた。しかも日本語でだ。人数の差を感じた。PyQtで英語記事をぐるぐる回って、不具合なのかバージョン違いなのか、やり方が間違ってるのかを、トライアンドエラーしていたようなことはない。そこには、日本語で読める記事が沢山あった。

音声や画像も扱ってみる、高速で再描画を繰り返してみる。エフェクトや数学的処理をして再描画を繰り返す。Pythonだと色々工夫をして30fpsを維持しようと頑張っていた。マウスやスライドバーの連続的なイベントへの対応も沢山工夫してた。でもWindowsだとあっっっというまに再描画が終わってしまう。Pythonおせーと思ったし、大声で叫んでいた人の気持ちが分かった。

これが専用に作られたツールとの差かと感じた。Pythonインタプリタ言語だ。スクリプトだ。でも。WEBの世界ではDjangoを初めとしてPythonは実用に耐えうる言語だ。「Dropboxは全部Pythonで信頼性の高いソフトウェアを作った」って言ってたし。Googleだって使っているし、それ以外でもPythonを一人前の言語って言えることは沢山ある。けど。デスクトップアプリでの成果は聞いたことが無かった。勘違いをしていたのは僕の方だったのかも。

かといって、自作の機械学習アルゴリズムC#へ移植するのは大変だ。アルゴリズムをこねくり回して、バッチ処理をするのには明らかにPythonが良い。

それならC#からPythonを呼びさせないかと考え始めた。GUIC#で準備して、アルゴリズムPythonで書いた奴を呼び出せたら最高だ。モチロン呼び出される側のPythonは不自由があるだろうけど、GUIのアプリケーションは、日頃使うというよりはデモで自身の成果を披露するときに使うのがメインだ。アルゴリズムを生み出すまではいつもどおりスクリプトとして接してあげて、GUIから呼び出すときはスマートにしてあげればいいだろう。そんなこんなでハイブリッドアプリの作り方を調べた。

C#または.NETまたはWindows Formアプリケーションから、pythonを呼び出す方法。

まぁ色々記事がでてくる。が、最新記事があまりない。需要ないのかな。pythonGUI関連の情報が少ない。PythonGUIの恩恵を受けるのはそんなにニッチなんだろうか。試行錯誤の結果。現時点での解を見つけたので。以降をその説明に費やそう。

2017年3月30日時点での

.NETでpythonを呼び出す方法

肝はC#で実装されたIronPythonを使うことだ。

まずはVisualStudioをインストールする。

  • VS2015 or VS2013のみ利用可能。(VS2017はプレビュー版のみ利用可能。現状未対応)

次に、VisualStudioでPythonを実行するために、PTVSをインストールする。リンク先から、VS2015用のmsiを使ってインストールする。PTVSの使い方については調べるといくらでもでてくる。これは、VS上でpythonを動かすだけだ。別に.NETからpythonを呼び出すとかどうとかではない。

そして要は、C#実装のIronPythonを使うことだ。

  • IronPython 2.7.7のダウンロード。(現時点2.7.7最新 2016/12リリース)

msi版でもいいし、zip版を展開するだけでも良い。

問題はモジュールをインストールできるかだ。

まずは2.7.5のドキュメントにしたがってpipを使ってみよう。

; -X:Frames is required when using pip
ipy.exe -X:Frames -m ensurepip

; Run from an Administrator console if using IronPython installer
ipy.exe -X:Frames -m pip install html5lib

だめだ、エラーがでた。Githubを観ると定番のissueのようだ。

C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7>ipy.exe -X:Frames -m ensurepip
Ignoring indexes: https://pypi.python.org/simple
Collecting setuptools
Collecting pip
Installing collected packages: setuptools, pip
Successfully installed pip-8.1.1 setuptools-20.10.1

C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7>ipy.exe -X:Frames -m pip install html5lib
Collecting html5lib
C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\pip\_vendor\requests\packages\urllib3\util\ss
l_.py:1: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not ava
ilable on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failur
es. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.
  from __future__ import absolute_import
  Downloading html5lib-0.999999999-py2.py3-none-any.whl (112kB)
    100% |################################| 122kB 809kB/s
Requirement already satisfied (use --upgrade to upgrade): setuptools>=18.5 in c:\users\user\downloads\ironpython-2.7.7-win\ir
onpython-2.7.7\lib\site-packages (from html5lib)
Collecting six (from html5lib)
  Using cached six-1.10.0-py2.py3-none-any.whl
Collecting webencodings (from html5lib)
  Downloading webencodings-0.5.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\setuptools\__init__.py", line 11,
 in <module>
      File "C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\setuptools\extern\__init__.py", l
ine 1, in <module>
      File "C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\pkg_resources\__init__.py", line
46, in <module>
      File "C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\pkg_resources\extern\__init__.py"
, line 42, in load_module
      File "C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\pkg_resources\_vendor\six.py", li
ne 701, in <module>
      File "C:\Users\USER\Downloads\IronPython-2.7.7-win\IronPython-2.7.7\Lib\site-packages\pkg_resources\_vendor\six.py", li
ne 692, in exec_
    AttributeError: 'module' object has no attribute '_getframe'

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in c:\users\user\appdata\local\temp\pip-build-aeiwzs\webencodings
\
You are using pip version 8.1.1, however version 9.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

VS2015上のPython Evnironmentを使ってみよう。 表示->その他のウィンドウ->python environmentsでironPythonを選択する。

msiIronPythonをインストールした場合はここに表示されている。zipを展開しただけなら、インタプリタを追加しよう。

近くにpipを使ってモジュールをインストールできるはずだ。 またしてもエラーだ。ないぶでは先ほどと同じように-X:Framesを使ってensurepipをインストールしてるが。失敗しているのが分かる。そろそろお手上げだ。

----- Installing pip -----
Restarting IronPython with -X:Frames
Installing with ensurepip
Ignoring indexes: https://pypi.python.org/simple
Collecting setuptools
Process is terminated due to StackOverflowException.
----- Failed to install pip -----

現時点では使えないかもしれない

.NETでPythonを試してみる 第4回

IronPython の使用を諦めることにしました。理由はモジュールのインストールができなかったことです。一番シンプルだと思っていた simplejson すらまともにできませんでした。正確には、インストールはできましたが、いざ import simplejson すると、動かない。他にも、CPythonと同じ方法でC言語ベースのライブラリと相互運用ができない2017/03/11時点で、Issueの数が700越え。あまりにも利用者の声に応える余裕がない。結局、ネット上で調べると、動かないという情報ばかり、でこれ以上貴重な時間を費やすことはできない、という判断に至りました。4日以上使いましたが、本当に無駄骨に終わりました。A certain engineer “COMPLEX”

IronPythonの現状について

現状は2014年12月にリリースされた2.7.5だ(2017/3/30)

2016/8/3の記事記事では、IronPython3プロジェクトが始まっているという。

そして、2017年12月 数年越しの2.7.7のリリース。2系では最後アップデートとなる。

このままだと

VS2017のPTVS正式対応を待ちながら、

IronPython3の正式リリースを待つしかなさそうだ。