SSブログ

IronPython と Firebird .NET Data Provider 雑感 [DotNET]

ここしばらく IronPython で Firebird .NET Data Provider を使った感想を少し。

まず、Firebird .NET Data Provider はよくできてる。
システムを .NET Framework + OSS な RDBMS(もしくは、クロスプラットフォームな RDBMS) で作りたいという強い要求があれば、 Firebird が候補になるのでは。
#そういう決め方をすることがあるのかどうかわからんが。

IronPython について言うと、python のシンタックスと CLR の型システムがうまいこと融合してる。Windows.Forms 等のクラスが、Python のクラスとしてきれいに扱える。非常に感心した。IronPython から使った場合に、もっと制約があるかと思ったが、.NET Framework 由来のクラスを使う場合にも、やりたいことは一通りできた。すばらしい。
言語のシンタックスの部分で CPython と IronPython での違いが少ないのにも驚いた。
CPython で実装されている多くのモジュールが存在しないことを除くと、 clr モジュールが追加されたことと、イベントハンドラの扱い(+= 演算子で追加)の点が CPython と違ってるくらい。
プログラミング言語の挙動で、両者が異なるなぁ、と気付いたのは IronPython では、辞書のキーは追加した順に取得されるけど、CPython ではハッシュされた値の順番、ってことくらい。
(下記ソース参照)

IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> d = {'Z':'z', 'X':'x', 'Y':'y'}
>>> print d
{'Z': 'z', 'X': 'x', 'Y': 'y'}
>>>
Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {'Z':'z', 'X':'x', 'Y':'y'}
>>> print d
{'Y': 'y', 'X': 'x', 'Z': 'z'}
>>>


IronPython のこの挙動は結構便利なんだけど、この仕様に依存したコーディングだと後々困るかなぁ?と思ってたりする。

IronPython を実際に使いこなそうとすると、(言語シンタックス上の)Pythonic な文化と、(ライブラリの).NET な文化の両方を理解し混ぜ合わせないといけないので、その点が一番の難関かなと思う。
僕の場合は主に、「XXXコントロールの使い方がわからないー」とかでの悩みが多かった。
ただ、慣れてしまうと、IronPython でコーディングって C# や VB より直感的に書ける。

みんな、もっと使えばいいのに。


DataGridView の使い方いろいろ(パクリ) [DotNET]

DataGridView は、いろいろ高機能すぎてよくわからん
MSDN のドキュメントも充実しているが、
http://msdn2.microsoft.com/ja-jp/library/e0ywh3cz(VS.80).aspx
高機能ゆえに、読んだだけではさっぱりわからん。

いろいろ試行錯誤しているものの取っ掛かりが欲しいよー、と思っていたが
「いろいろ備忘録日記」さんのところにあり
http://d.hatena.ne.jp/gsf_zero1/

http://d.hatena.ne.jp/gsf_zero1/20070129/p1
http://d.hatena.ne.jp/gsf_zero1/20070130/p1
http://d.hatena.ne.jp/gsf_zero1/20070131/p1
http://d.hatena.ne.jp/gsf_zero1/20070201/p1
http://d.hatena.ne.jp/gsf_zero1/20070202/p2
http://d.hatena.ne.jp/gsf_zero1/20070207/p1
http://d.hatena.ne.jp/gsf_zero1/20070221/p1

後で読む

(追記)ADO.NET と絡めて関連することを、ちょっと前に書いてた
http://blog.so-net.ne.jp/nakagami/2007-01-17
ここ↓も見ておくべし(→自分)
http://msdn2.microsoft.com/ja-jp/library/ms171596(VS.80).aspx


IronPython での文字列のファイル出力 [DotNET]

SQLServer のデータを取得してテキストファイルに出力したい。

IronPython から SQLServer にアクセスするのはこんな感じ
http://blog.so-net.ne.jp/nakagami/2006-11-08

System.Data.SqlClient.SqlCommand の ExecuteReader() で返ってくる結果は、
UNICODE になってるので、それを print でテキストファイルに出力したかった。
コンソールへの出力は、ここら↓でやったので、
http://blog.so-net.ne.jp/nakagami/2006-04-12-1
ファイル出力でも同じだろうとたかをくくってた。

ところが、どうにもうまくいかない。
コンソールへの出力はうまくいくが、今回は Windows.Forms アプリケーションとして作りたいので、「コンソールの出力をリダイレクトして下さい」というわけにもいかない。
結局、ここ↓にたどり着いた。
http://www.python.jp/pipermail/python-ml-jp/2006-September/003665.html
(正確には、このメールは、以前読んでいたんだけど、意味を理解してなかった)

defaultencoding に依存する書き方はあまりしたくなかったので
結局バイナリモードで開いて、自分の好きな encode (今回で言えば cp932) を指定して出力するようにした。

こんな感じ

    f = open(r'foo.txt', 'ab')
    for cmd in SqlCommand('select bar from baz', db_conn).ExecuteReader():
        print >>f, cmd['bar'].encode('cp932')  + '\r'
    f.close()


改行コードも変換してくれないので、\n が出力される直前に \r を出力したところがポイントかな。


Windows フォームの開始位置を指定 [DotNET]

http://www.atmarkit.co.jp/fdotnet/dotnettips/349location/location.html
Windows.Forms.Form の Left,Top プロパティに設定
#Location = Point(x, y)でも良い
と一緒に、

this.StartPosition = Forms.FormStartPosition.Manual

を設定してあげないといけないみたい。
小一時間はまった。

ダイアログの開始位置については、(親フォームとの関連もあって)また別みたい
http://www.atmarkit.co.jp/fdotnet/dotnettips/353dlglocation/dlglocation.html

慣れるまでは、いろいろ悩むなぁ。


ADO.NET の DataSet というモデルがよくわからない [DotNET]

DataGridView コントロール と、RDBMS のデータを連携させたいのだが、
ADO.NET の DataSet を使うモデルがよくわからない。なるほど!っていう納得感がない。
複数のテーブルを JOIN した時のテーブル名の指定はどうすんだろうか?
DataSet って JOIN しないで、テーブル毎に SELECT した時にしか使わない(使えない)んだろうか?そうだとすると、DataSet を使う場面ってそんなにないよなぁ。

とりあえず、Firebird を使ったサンプルを発見したので URL をメモっておく
http://d.hatena.ne.jp/gsf_zero1/20061228

DataGrid のマニュアルを見て、BindingSource を使わない方法で何とかするか・・・
http://msdn2.microsoft.com/ja-jp/library/e0ywh3cz(VS.80).aspx

「方法 : 連結されていない Windows フォーム DataGridView コントロールを作成する」だな
http://msdn2.microsoft.com/ja-jp/library/zf3zx9fy(VS.80).aspx


.Net Framework 2.0 を静かに(無人モードで)インストール [DotNET]

まず、Windows Installer 3.1 をインストールする(必要な場合)

WindowsInstaller-KB893803-v2-x86 /quiet /norestart /log:"%temp%\Installer31.log"


と /quiet /norestart /log オプションをつける(/log は別にいらんけど)

次に、.Net Framework 2.0 をインストール

dotnetfx.exe /Q


と /Q オプションをつける

ちなみに、Visual Studio 2005 を無人でインストールする話は
ここ↓あたり(機械翻訳で読みにくい)
http://support.microsoft.com/kb/913445
(Visual Studio 2005 を無人でインストールする状況が想像できんけど・・・)

追記(2007/1/30)
WindowsInstaller に /passive というオプションがある。 /quite の代わりに使うといいかも。
passive は、ユーザーを介さない(ボタンを押さない)が進行状況は見られる。


IronPython でコンソールウィンドウが出てしまう件 [DotNET]

SQLServer のデータを操作する小道具が必要になったので、
IronPython でちょっとした Windowws.Forms アプリを書いてみる。

EXE を作ることもできたはずだぞ、と思っていたが、いざ出来上がって

ipy.exe -X:SaveAssemblies foo.py
でできた foo.exe をエクスプローラーから起動してみると
・・・コンソール(コマンド)画面が出てしまう。がっくし。
ipyw.exe -X:SaveAssemblies foo.py
でできた foo.exe でも同じ。

結局、
[とあるフォルダへの絶対パス]\ipyw.exe foo.py
というショートカット(作業フォルダは[とあるフォルダへの絶対パス]と同じ)を作成したら、コンソール画面を出さずに起動できた。
コンソール画面の出ない exe はできないもんかなぁ、と思ってるけど、とりあえずは問題解決。

ちなみに、「とあるフォルダ」には
IronPython.dll
IronMath.dll
ipyw.exe
foo.py(←実行したい Python のソース)
をコピーしておく。
私は、デバッグ用に ipy.exe もコピーしといた。


VS2005でGUIを作ってIronPythonで制御するやり方(へのリンク)とか [DotNET]

VB.NET のソースを読むことになるかもしれない今日この頃。
いまさら VB.NET の本を買うのは癪なので、手近にあった C# を本を読み返してみたり
http://blog.so-net.ne.jp/nakagami/2006-03-29-1
Visual Studio Express Edition の C# と VB.NET をインストールしてフォームにコントロールをペタペタ貼ったりメッセージボックスを表示する処理をちょこっと入れたりしてみている。

昔(VC6の頃まで)は、コントロールの情報はリソースファイルとか「特別な形式の」ファイルに書かれたものがいっぱいあったけど、いまどきはフォームデザイナでデザインすると、VB や C# の普通のソースコードになってくれるようで、知らなきゃ(覚えなきゃ)いけない黒魔術が少ない。ソースを順に追ってけば、どこがどうなってるかだいたいわかりそうで良い。まだ、よくわからないところもあるけど、IDE の力を借りれば、私にもなんとかなりそう。遂に俺も VB プログラマとしてデビューかな(と言ってみたりして)。

ところで、ふにゃるんさんの
「VS2005でGUIを作ってIronPythonで制御するやり方」
http://d.hatena.ne.jp/Wacky/20060910/1157881776
は、ここに URL をメモっておく価値あり。
処理の多くを IronPython で書くのは賛否が分かれると思うが、マクロ言語みたいに Python が組み込めると良さそうだなぁ。

Python カテゴリと
http://d.hatena.ne.jp/Wacky/searchdiary?word=%2a%5bpython%5d
.NET カテゴリもも見ておくべし(→自分)
http://d.hatena.ne.jp/Wacky/searchdiary?word=%2a%5b%2eNET%5d


IronPython で Windows.Forms [DotNET]

ボタンが押されたらテキストボックスに入ってる内容に従って何か処理する・・・のサンプルコード

import clr
clr.AddReference("System.Windows.Forms")
from System.Windows import Forms

class SimpleInputForm(Forms.Form):
    def __init__(self):
        self.Height = 120
        self.Width = 400
        self.Text = 'IronPython Windows.Forms sample'

        self.Controls.Add(Forms.Label(Left=20, Top=10, Text="Input your name."))
        self.MessageText = Forms.TextBox(Left=20, Top=35, Width=350)
        self.Controls.Add(self.MessageText)
        
        self.MessageButton = Forms.Button(Text="&Message", Left=100, Top=60)
        self.MessageButton.Click += self.OnClickHello
        self.Controls.Add(self.MessageButton)

        self.QuitButton = Forms.Button(Text="&Quit", Left=230, Top=60)
        self.QuitButton.Click += self.OnClickClose
        self.Controls.Add(self.QuitButton)

    def OnClickHello(self, sender, args):
        if self.MessageText.Text:
            message = "Hello, " + self.MessageText.Text + "!"
        else:
            message = "Hello, world!"
        Forms.MessageBox.Show(message)
        
    def OnClickClose(self, sender, args):
        self.Close()

if __name__ == '__main__':
    app = SimpleInputForm()
    Forms.Application.Run(app)

IronPython で IsolatedStorage [DotNET]

1こ前のエントリの続き。とりあえず、1行書いて、1行読んでみるサンプル。

from System.IO import FileMode, StreamWriter, StreamReader
from System.IO.IsolatedStorage import IsolatedStorageFileStream

def foo_writer(s):
    cfg = IsolatedStorageFileStream("foo.cfg", FileMode.Create)
    sw = StreamWriter(cfg)
    sw.WriteLine(s)
    sw.Close()
    cfg.Close()

def foo_reader():
    cfg = IsolatedStorageFileStream("foo.cfg", FileMode.Open)
    sr = StreamReader(cfg)
    s = sr.ReadLine()
    sr.Close()
    cfg.Close()
    return s

if __name__ == '__main__':
    foo_writer('Hello world!')
    print foo_reader()


本当は XML ファイルにオブジェクトをシリアライズしてみたかったんだけど、
System.Xml.Serialization でシリアライズする場合は、クラスにパラメータなしのコンストラクタが必要だったりの制約があるみたい。結果、IronPython のオブジェクトではうまくいかなくて挫折。