Python for .NET の微続き。一つ前よりは進展。

今度はちゃんと Python for .NET の話。

眠いからもう今日はやめようかとも思ったが、やり始めたらあっという間だったもんで。

ちょっとびっくりしたんだけど、「IDE なしで」という絞込みをしたわけでもないのに、真っ先にそういう公式説明があるのがわかった。

一つ前のを書いてたときから、「最初に遊ぶならこれ」と思ってたそのまんまがこれ:

 1 # -*- coding: utf-8 -*-
 2 # ---------------------------------------------------
 3 def build_cs():
 4     # Python と C# でアプリケーションを作る、というつもりなら、
 5     # 開発対象の C# をこうやって python からビルドしちまうのもテンポよくて
 6     # ええかもしらんね。特に「管理対象前の、書き始め」時点では。
 7     import subprocess, os
 8     try:
 9         os.remove("MathLibrary.dll")
10     except Exception:
11         pass
12     subprocess.check_call(
13         [
14             # csc -nologo -target:library -out:MathLibrary.dll Add.cs Mult.cs
15             "csc.exe",
16             "-nologo",
17             "-target:library",
18             "-out:MathLibrary.dll",
19             "Add.cs",
20             "Mult.cs",
21             ]
22         )
23 def write_cs():
24     # さらに気軽にということなら、C# コードさえも python コード内に
25     # 文字列で埋め込んで、書き出してビルド、なんてことさえ…。
26     # こんな具合:
27     import io
28     io.open("Add.cs", "w").write("""
29 namespace UtilityMethods
30 {
31     public class AddClass 
32     {
33         public static long Add(long i, long j) 
34         { 
35             return (i + j);
36         }
37     }
38 }
39 """)
40     #
41     io.open("Mult.cs", "w").write("""
42 namespace UtilityMethods 
43 {
44     public class MultiplyClass
45     {
46         public static long Multiply(long x, long y) 
47         {
48             return (x * y); 
49         }
50     }
51 }
52 """)
53 write_cs()
54 build_cs()
55 # 無論これを「正規の開発プロセス」として採用することは絶対にやらんと思うし、
56 # 当然こんなんすぐに保守不能になるのは明白だけれど、「C# の小さなユーティリティ
57 # クラスを手っ取り早く書きたいのだ今すぐに」てのには結構いいよねこういうの。
58 # (とはいえワタシは「C# でのお仕事」は当面ご用事ねぃけど。)
59 
60 
61 
62 # ---------------------------------------------------
63 import clr
64 from System.Reflection import Assembly
65 #print(dir(Assembly))
66 
67 # 各やりかたの違いは理解出来てないが以下3つどれでも期待通り動くみたい。
68 clr.AddReference("MathLibrary")
69 #Assembly.LoadWithPartialName("MathLibrary")
70 #Assembly.LoadFrom("MathLibrary.dll")
71 
72 def test_cscode():
73     r"""
74     >>> import UtilityMethods
75     >>> print(UtilityMethods.MultiplyClass.Multiply(2, 3))
76     6
77     >>> print(UtilityMethods.AddClass.Add(4, 5))
78     9
79     """
80     # こういう「C# 開発の TDD」てのもおもろいアイディアかもしらんね、
81     # 「C# 開発」が目的なら。
82     pass
83 
84 
85 if __name__ == '__main__':
86     import doctest
87     doctest.testmod()
※注:一つまだよくわかってない(というか記憶から抜け落ちてる)のが、いわゆる COM だと GUID を「公に宣言」しなけりゃならんのね。それを津々浦々にさらすことで「公式の API」として誰からも使える。(デプロイの話じゃなくて、文字通り identity の話。) これに類する話が .NET な DLL にもあった気がするんだけど、この今回の遊びではそこらへんのことは「出来ちゃったもんだから考えてない」。あれかな、「マニフェストをちゃんと書く」だけかも。ちゃんと理解できたらそのうち書く(かも)。

何を、どれを開発の「主食」にするかにもよるけれど、「C# で開発するのがお仕事」というケースでこういう始め方をするのも、なかなかに「億劫じゃない」くてええんじゃないのかな、って話。こういう「Python をテスターとして使う」考え方は、C/C++ 開発の際も結構考えます、アタシは。

あとさ、「Python の異言語交流」のメインは C/C++ なわけで、「性能がために C 拡張もしくは Cython」てのがまぁ主流なわけじゃん? CPython では。ただ、「Windows 箱の外から出(れ)ない」ことを受け容れる限りは、ひょっとすると場合によっては「Cython を性能目的に使うのと同じ目的で」部分 C# 化する、て考え方も、ひょっとしたらないではないのかもなぁ、と、おぼろげながら思ってる。

無論「Python を主食にする場合」に .NET 活用したい一番のモチベーションは普通は「使いたい機能・ライブラリが .NET にある」場合だろうけど、こんな具合に色々自由に考えれると思う。

あぁ、今回の話とはちょっとズレるけど、「.NET てことはアレだ、XAML 出来るぞ、WPF 出来るぞ」と考える人は正解。アタシが WPF してたのはもう遥か昔だが、「本当に使いやすいかどうかはともかくとして、考え方は大好き」になった。かなり良く練られてて、非常に面白かった。そういうわけで「いつかやろうと思うけどさすがに敷居は高いだろうな」と思っていたのだが、Python for .NET の Git レポジトリにしっかりデモがあるのであった。やったね。(なんの問題もなく動く。)