SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

IronPythonの特徴

.NETとの相互運用性

 IronPythonを設計するうえでの難題の1つが、この言語の対象者層が2つに分かれていて、それぞれの要求を満たす必要があるということです。すなわち、C言語ベースの標準のPythonにできるだけ近い動作を実現しつつ、.NET Frameworkとの相互運用性も厳密に実現しなくてはなりません。時には、この2つの要求が相反することもあります。たとえば、次のコードはどのように動作するのが適切でしょうか。

s = 'hello, world!'
s.ToUpper()

 Pythonでは、文字列型にToUpperメソッドがないので、このコードでは例外が発生するのが適切です。一方、.NETでは、この文字列に対してToUpper関数を呼び出した場合、"HELLO, WORLD!"が返るのが適切です。両者の要件は明らかに矛盾しています。

 IronPythonでは、この問題に対処するために、既定では標準のPythonに準拠しつつ、開発者が明示的に指定した場合には.NETとの相互運用性を厳密に確保できるという方式を取り入れています。Pythonも.NETと同様、モジュールや名前空間といった単位でコードを取りまとめます。IronPythonにはclrという特別なモジュールがあり、このモジュールをインポートすると、.NETとの相互運用性を利用するという合図になります。次に示すIronPythonの対話型セッションは、import clrを使用した場合の例です。

>>> s = 'hello, world'
>>> s.ToUpper()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no 
                attribute 'ToUpper'
>>> import clr
>>> s.ToUpper()
'HELLO, WORLD'

 import clrを呼び出していない場合、文字列に対してToUpperメソッドを呼び出すことはできません。Pythonの文字列オブジェクトにはToUpperメソッドがないため、IronPythonでもこのメソッドはないものとして扱われます。しかし、import clrを呼び出すと、文字列オブジェクトのすべてのメソッド(Pythonと.NETネイティブの両方)が利用可能になります。

 clrモジュールは外部アセンブリの読み込みにも利用します。たとえば、.NETのXML処理クラス(XmlReaderやXmlDocumentなど)を利用するときには、System.Xml.dllへの参照を追加する必要があります。C#の場合、こうした参照の追加はコンパイル時に宣言的に行います。一方IronPythonの場合、コンパイル時というものがないため、参照の追加はコード内の命令によって行います。その後で、現在のスコープにクラスをインポートすれば、他のPythonオブジェクトと同様に扱えます。

import clr
clr.AddReference('System.Xml')
from System.Xml import XmlDocument
xml = XmlDocument()
xml.Load('http://devhawk.net/rss.aspx')

 上のコードの処理内容は自明と思いますが、何点か補足しておきます。1つは、Pythonにはnewステートメントがない点です。型のインスタンスの生成は、型を関数のように呼び出すことで行います。もう1つは、クラスのインポートについてです。C#の場合は、usingステートメントを使って名前空間からクラスをインポートするのは、記述を簡略化するためのオプションの方法です。一方Pythonの場合、これは必須です。たとえば、次のように記述したコードは動作しません。

import clr
clr.AddReference('System.Xml')
# the following line doesn't work
xml = System.Xml.XmlDocument() 

 from...import形式のステートメントでは、短い名前をインポートします。名前空間の完全修飾名を使用するには、import System.Xml.XmlDocumentのように記述します。importでは、競合を回避するための名前の変更も可能です。その場合は、import <real name> as <new name>という形で記述します。

 必要なアセンブリへの参照を追加し、型のインポートを行えば、.NET FrameworkのほぼすべてをIronPythonから利用できます。.NETの型のインスタンスを作成できるのはもちろん、.NETのイベントの利用、.NETのインターフェイスの実装、.NETの型の継承といったことも可能です。たとえば、次に示すコードはIronPythonのチュートリアルから引用したもので、Windowsフォームを利用しています。

# the winforms module in the tutorial directory
import winforms
from System.Windows.Forms import *
from System.Drawing import *
def click(*args): 
   print args
   f = Form()
   f.Text = "My First Interactive Application"
   f.Click += click
   f.Show()

 ただし、IronPythonからではできないことが1つあります。コードに属性を付加することです。.NET Frameworkのうち、WCFのコントラクトやXMLのシリアル化など、属性を必要とする部分については、IronPythonでは利用できません。こうしたライブラリはカスタム属性を基盤としています。カスタム属性とは、既存の静的型を拡張するためのカスタムのメタデータのように機能するものです。Pythonの場合、オブジェクトに静的型がないので、カスタム属性を付加する先がありません。

 .NETの相互運用性に関してもう1つ述べておきたいのは、基本的に一方向の関係だということです。つまり、静的型付け言語で作成した.NETのクラスをPythonから呼び出すのは簡単ですが、動的型付け言語のオブジェクトを静的型付け言語から呼び出すのは、現時点では簡単ではありません。静的言語では、コンパイル時の型のメタデータを利用してメソッド呼び出しをディスパッチしますが、Pythonのような動的型付け言語では、そもそもメタデータが存在しません。もちろん、多言語というCLRの特性を考えると、静的型付け言語から動的型付け言語のコードを呼び出すという処理は、将来実現できればと思っています。

IronPythonの埋め込み

 Pythonは、埋め込みが簡単な言語として注目を集めています。IronPythonも同様に、.NETアプリケーションに簡単に埋め込むことができ、スクリプトやマクロを利用した開発を実現できます。

 IronPython 1.xでは、埋め込みの処理において、PythonEngine型を全面的に利用していました。次に示すのは、対話型のコンソールからPythonEngineを利用する例です。

>>> import clr
>>> clr.AddReference("IronPython.dll")
>>> from IronPython.Hosting import PythonEngine
>>> pe = PythonEngine()
>>> pe.Evaluate('2+2')
4

 この例の場合は、ホストされているPython環境にホスト側との関連付けがないため、実行できるコードがかなり限られていますが、PythonEngineのGlobalsコレクションを使えば、アプリケーションのオブジェクトモデルをPython環境に対して公開できます。

 IronPython 2.0では、ホストを行うためのコードは少々複雑になります。

import clr 
clr.AddReference("IronPython.dll")
from IronPython.Hosting import PythonEngine 
pe = PythonEngine.CurrentEngine 
scope = pe.CreateScope()
source = pe.CreateScriptSourceFromString('2+2')
result = source.Execute(scope)

 IronPython 2.0のコードが複雑になった理由の1つは動的言語ランタイム(DLR)です。DLRはCLRの拡張で、動的言語に必要な共通機能を提供します。この中には、共通のホスティングAPIも用意されています。DLRをホストするアプリケーションが、DLRをターゲットとした任意の言語をサポートできるようにするAPIです。つまり、DLRのホスティングAPIを利用したアプリケーションでは、IronPythonだけでなく、IronRubyやManaged JavaScriptなど、DLRを基盤としたサードパーティ製の任意の言語をサポートできます(詳しくはホスティングAPIの説明を参照)。

 空白の使い方から動的型付けに至るまで、Pythonでの開発は、C#やVBとは大きく異なるのは確かです。私自身、C#からPythonに転向して日が浅いので、最初は奇妙な感じがするというのは大いに共感できます。しかし、そこを通り過ぎれば、Pythonの生産性の高さに目を見張ることと思います。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Harry Pierson (Harry Pierson )

 IronPythonのプログラムマネージャ。Microsoftで10年のキャリアを誇り、アーキテクチャやサービスにかなりの力を注いできた。自身のブログでは、技術、プログラミング、アーキテクチャなどの話題を取り上げ、時にはアイスホッケーについても語る。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3457 2009/01/28 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー