ふにゃるんv2

もとは、http://d.hatena.ne.jp/Wacky/

IronPythonの復習

IronPythonが1.0になって、Pythonや.NETな方々の間で 話題になっているようです。
私も、再度復習する事にしました。


とりあえず、自分が興味深いと思った以下の項目を説明します。

  • .NETとの華麗な結合(文字列クラスの例)
  • 既存のPythonライブラリを取り込む貪欲さ
  • Win32APIを(簡単に)呼び出す方法
  • IronPythonエンジンのオンラインヘルプの在り処
  • VS2005にIronPythonが組み込まれる?


個人的には、C#IronPythonの間を行き来する方法を、もう少し調べたいですね。

.NETとの華麗な結合(文字列クラスの例)

件のビデオを見ていて気付いたんですが、"import clr"した前と後で、メソッドが拡張されるんですね。

$ ipy
IronPython 1.0.60816 on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> dir()
['__builtins__', '__doc__', '__name__', 'site']
>>> dir("")
['__add__', '__class__', '__cmp__', '__contains__', '__doc__', '__eq__', '__geti
tem__', '__getnewargs__', '__getslice__', '__init__', '__len__', '__mod__', '__m
odule__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr
__', '__rmul__', '__str__', 'capitalize', 'center', 'count', 'decode', 'encode',
 'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdecimal', '
isdigit', 'islower', 'isnumeric', 'isspace', 'istitle', 'isunicode', 'isupper',
'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust', 'rspl
it', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title'
, 'translate', 'upper', 'zfill']
>>> import clr
>>> dir()
['_', '__builtins__', '__doc__', '__name__', 'clr', 'site']
>>> dir("")
['Add', 'Capitalize', 'Center', 'Clone', 'Compare', 'CompareOrdinal', 'CompareTo
', 'Concat', 'Contains', 'Copy', 'CopyTo', 'Count', 'Decode', 'Empty', 'Encode',
 'EndsWith', 'Equals', 'EqualsRetBool', 'ExpandTabs', 'Finalize', 'Find', 'Forma
t', 'GetEnumerator', 'GetHashCode', 'GetLength', 'GetNewArgs', 'GetSlice', 'GetT
ype', 'GetTypeCode', 'Index', 'IndexOf', 'IndexOfAny', 'Insert', 'Intern', 'IsAl
num', 'IsAlpha', 'IsDecimal', 'IsDigit', 'IsInterned', 'IsLower', 'IsNormalized'
, 'IsNullOrEmpty', 'IsNumeric', 'IsSpace', 'IsTitle', 'IsUnicode', 'IsUpper', 'J
oin', 'LJust', 'LStrip', 'LastIndexOf', 'LastIndexOfAny', 'Length', 'Lower', 'Ma
ke', 'MakeDynamicType', 'MemberwiseClone', 'Modulus', 'Multiply', 'Normalize', '
NotEquals', 'PadLeft', 'PadRight', 'RFind', 'RIndex', 'RJust', 'RSplit', 'RStrip
', 'Reduce', 'ReferenceEquals', 'Remove', 'Replace', 'ReverseMultiply', 'Split',
 'SplitLines', 'StartsWith', 'Strip', 'Substring', 'SwapCase', 'Title', 'ToCharA
rray', 'ToLower', 'ToLowerInvariant', 'ToString', 'ToUpper', 'ToUpperInvariant',
 'Translate', 'Trim', 'TrimEnd', 'TrimStart', 'Upper', 'ZFill', '__add__', '__cl
ass__', '__cmp__', '__contains__', '__doc__', '__eq__', '__getitem__', '__getnew
args__', '__getslice__', '__init__', '__len__', '__mod__', '__module__', '__mul_
_', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__',
'__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'exp
andtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'islowe
r', 'isnumeric', 'isspace', 'istitle', 'isunicode', 'isupper', 'join', 'ljust',
'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust', 'rsplit', 'rstrip', 's
plit', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'u
pper', 'zfill']

"import clr"する前は、文字列クラスは普通のpythonと同じメソッドを持っているのですが、"import clr"後、.NETの文字列クラスのメソッドが侵入しているんですね。
シームレスに使えるようになっている訳です。これはすごい。


後、importした.NETクラスのヘルプが統合されるんですね。

IronPython 1.0.60816 on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> import clr
>>> import System
>>> help(System.String)
Help on str in module __builtin__

 |      T.__new__(S, ...) -> a new object with type S, a subtype of T
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T
 |
 |  Data and other attributes defined here:
 |
 |      Add(...)
 |              x.__add__(y) <==> x+y
 |      Capitalize(...)
 |              str capitalize(str self)
 |      Center(...)
 |              str center(str self, int width)
 |              str center(str self, int width, Char fillchar)
 |      Clone(...)
 |              object Clone(self)
...
 |      strip(...)
 |              str strip(str self)
 |              str strip(str self, str chars)
 |      swapcase(...)
 |              str swapcase(str self)
 |      title(...)
 |              str title(str self)
 |      translate(...)
 |              str translate(str self, dict table)
 |              str translate(str self, str table)
 |              str translate(str self, str table, str deletechars)
 |      upper(...)
 |              str upper(str self)
 |      zfill(...)
 |              str zfill(str self, int width)

先の文字列クラスも、helpコマンドで参照すると、確かに普通のpythonの文字列メソッドと、.NETの文字列メソッドが結合しているのがわかります。

既存のPythonライブラリを取り込む貪欲さ

チュートリアルを見ていると、sys.path.append() を使って、既存のPythonパスを割り当てているんですね。

私、勘違いしていて、IronPythonの中に既存のPythonライブラリと同じモジュールか何かが内蔵していて、パスを割り当てる事で使用可能になるのかと思ってましたが、全然違いました。

$ ipy
IronPython 1.0.60816 on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> import os
Traceback (most recent call last):
  File , line 0, in <stdin>##3
  File , line 0, in __import__##7
ImportError: No module named os
>>> import sys
>>> import os
Traceback (most recent call last):
  File , line 0, in <stdin>##9
  File , line 0, in __import__##7
ImportError: No module named os
>>> sys.path.append(r"c:\tool2\python24\lib")
>>> import os
>>> os.getcwd()
'F:\\Wacky\\Test\\python\\IronPython\\IronPython-1.0-Bin\\IronPython-1.0\\Tutorial'

本当に既存のPythonライブラリを取り込んで使用しているんですね。


ちなみに、取り込む事のできるのは、純粋なpythonコードのみっぽいです。(違うのかな?)
.pyd(DLLみたいなもん)を読み込んでくれるかな?と思ったんですが、流石に無理っぽいです。


DLLを呼び出す ctypesライブラリが、_ctypes.pydとか利用するんで、ちょっと残念だったんですが、IronPythonのMLを見ていると、ctypesのIronPython版を作ろうとされる方が居られるようです。


1.0版から動かそうとすると、どうも動いてくれてないように見えるんですが、今後に期待という所でしょうか。

Win32APIを(簡単に)呼び出す方法

IronPython版のctypesは、まだ完全ではない。
では、どうやってWin32 APIを「簡単に」呼び出せば良いか?


チュートリアルを読みながら思いついたのは、以下の方法です。

  1. pinvoke.netで、呼び出したいWin32 APIを検索する。
  2. チュートリアルの「Tutorial 5: Extending IronPython」の「Exercise 1: Extending using C#」を参考に、csextend.cs ファイルに、Win32 APIを呼び出すコードを貼り付ける。
  3. Tutorialフォルダの、csx.batを動かして、作成した csextend.cs ファイルを、アセンブリモジュール(.NET用のDLLみたいなもの)にコンパイルする。
  4. IronPythonから、コンパイルしたアセンブリモジュールを呼び出す。


例えば、user32.dllのMessageBox関数を呼び出すとします。
csextend.csには、以下のように記述します。

using System;
using System.Runtime.InteropServices;

public class Simple {
    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    public static extern uint MessageBox(IntPtr hWnd, String text, String caption, uint type);
}


これを、csx.batからコンパイルすると、csextend.dll ファイルが出来上がります。
IronPythonを立ち上げて、以下のように入力すれば、作成した MessageBox関数が呼び出せます。

F:\Wacky\Test\python\IronPython\IronPython-1.0-Bin\IronPython-1.0\Tutorial>..\ip
y
IronPython 1.0.60816 on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> import clr
>>> clr.AddReferenceToFile("csextend.dll")
>>> import Simple
>>> Simple.MessageBox(IntPtr(0), "hello IronPython", "hello", 0)
Traceback (most recent call last):
  File , line 0, in <stdin>##15
NameError: name 'IntPtr' not defined
>>> from System import IntPtr
>>> Simple.MessageBox(IntPtr(0), "hello IronPython", "hello", 0)
1
>>>

IronPython1
IronPython1 posted from フォト蔵


IntPtrを使う場面は、System空間からimportすればOKのようです。
(「new IntPtr」がないぞ?と思いの方が居られるかも知れませんが、pythonには「new」演算子はありません)


参考:

IronPythonエンジンのオンラインヘルプの在り処

チュートリアルの最後の方になると、C#等からIronPythonを呼び出す手法や組み込み方について、色々解説しています。


例えば、「Tutorial 6: Embedding IronPython」の「Exercise 1: IronPython as an expression evaluator」では、以下のコードでIronPythonのエンジンを簡単に呼び出せる事が示唆されています。

using System;
using IronPython.Hosting;

public class Eval {
    public static void Main(string[] args) {
        PythonEngine pe = new PythonEngine();
        Console.WriteLine(pe.Evaluate(args[0]));
    }
}


ところで、IronPythonエンジンのオンラインヘルプですが、docフォルダに IronPythonApiReference.chm が転がっています。
IronPython2
IronPython2 posted from フォト蔵


これを見ると、PythonEngine.Evaluateメソッドは、3つほどバージョンがあるようですね。

VS2005にIronPythonが組み込まれる?(追加)

関係者さん?のBlogを見ていると、VS2005 SDKIronPythonを組み込むらしいことの下りがありました。

以下、翻訳Webサイトで翻訳されたものを、そのまま転載。

原文:
As a note about the VSSDK and IronPython 1.0...our latest CTP release (August 2006) was locked down in late July 2006, and as such, does not have the final 1.0 IronPython bits. However, for our "RTM" quality version 3 of the VS 2005 SDK, we will be shipping IronPython 1.0 inside it for the IronPythonIntegration sample. This RTM Version 3 of the SDK which includes IronPython 1.0 bits will be the September 2006 version and should hit the web sometime before the end of September. We're going through final testing and security reviews now, so the end is in sight.

翻訳:
VSSDKとIronPython1.0に関する注として…私たちの最新のCTPリリース(2006年8月)は、7月の2006下旬に、そういうものとしてロックされて、最終的な1.0IronPythonビットを持っていません。 しかしながら、私たちのV2005SDKの"RTM"上質のバージョン3のための私たちはIronPythonIntegrationのサンプルのためにIronPython1.0をそれに出荷するでしょう。 IronPythonを1.0ビット含んでいるSDKのこのRTMバージョン3は、2006年9月のバージョンであり、9月の終わりまでにいつか、ウェブを打つべきです。 私たちが今最終的なテストとセキュリティレビューを調べているので、終わりは見えています。

used by. http://www.excite.co.jp/world/

どうも、9月のリリースで組み込むらしいですね。わくわく。


参考: