IronPythonリハビリメモ
ここ1年以上、VB.NET・JavaScript・C#・XAMLしか書いてなかったので、IronPython(というかPython自体)をほとんど忘れてしまっていた。なので未来の自分が読んだらコードが書ける程度にメモを残しとく。
一日で書けるやろ…ぐらいで書いてたら意外と終わらなかったので、これから少しずつチマチマ追記していく予定。
Hello World
print "こんにちわ せかい"
IronPython では CPython とは違って、マルチバイト文字列であっても、u"こんにちわ せかい"みたいに u つけなくていい。
Python では null は None
ちなみに True とか False とか、みんな先頭大文字。
if文
if a == True: return "a" elif b == True: return "b" else: return "other"
&& とか || は使えないので、and とか or とか書きましょう。あと、条件式が横に長くなって途中改行したいときは、行末に \ を入れると良い。
if is_foo_bar_baz_flag == True \ or is_hoge_fuga_piyo_flag == True: print "この変数名は流石にないわ"
何も処理をしないブロックを記述する
if foo = True: pass
Python に switch文 は存在しない
素直に if文 書きましょう。
リスト
list = ['foo', 'bar', 'baz'] print list[1]
リストをループで処理する
for v in list: print v for i in range(len(list)): print i for i, v in enumerate(list): print "%s - %s" % (i, v)
リスト内包
そのうち書く
タプル
そのうち書く
ディクショナリ
そのうち書く
for文
そのうち書く
イテレータ
そのうち書く
ジェネレータ
そのうち書く
sprintf()的な文字列フォーマット
print "%s : %s" % (100, 500)
書きかけ。
関数
def hoge(x, y): return x + y
return で何も返さない場合は None が返る。
多値を返す
def hoge(x, y): return (x, y) a, b = hoge(1, 2)
正確にはシーケンスを変数にばらして受け取る、と表現した方が正しいかも。
デフォルト引数
def hoge(x, y = 1): return x + y
デフォルト引数の右辺には外部スコープの変数を割り当て可能。ただし、1回しか評価されないので、後から外部スコープの変数の値が変わっても追従はされないので注意が必要。
i = 10 def hoge(x, y = i): return x + y
キーワード引数
def hoge(x, y): return x + y hoge(x = 100, y = 500)
関数定義側の構文は特に変わらず、コールする側の記法が異なるだけ。引数の頭に ** を付けるとディクショナリを渡せる。
args = {'x': 5, 'y': 10} hoge(**args)
別に変数に代入しなくてもおk
hoge(**{'x': 5, 'y': 10})
任意引数リスト(可変引数)
def hoge(x, *args): result = x for v in args: result += v return result hoge(1) # 1 hoge(1, 2, 3) # 6
キーワード引数も可変にできる。定義されていない仮引数名が指定された場合、ディクショナリとして値が渡される。
def hoge(x, **args): for k, v in args.iteritems(): print "[%s] %s" % (k, v) hoge({'x': 5, 'y': 10, 'z': 15}) # [y] 10, [z] 15 が出力される。
「* 仮変数」と「** 仮引数」は混在可能。ただし、* の方を先に書かないとだめ。
def hoge(x, *args, **keys): pass
リストやタプルを展開して引数として扱う / JavaScript でいうところの Function.apply(this, args)
foo(*(1, 2)) bar(*[1, 2, 3, 4])
キーワード引数にディクショナリを渡したい場合は前述のとおり。
hoge(**{'x': 5, 'y': 10, 'z': 15})
デコレータ
そのうち書く
匿名関数(ラムダ)
lambda x, y: x + y
lambdaには単一式しか書けない。無茶したらブロックを書けるけど、まさにバッドノウハウ。
Python の lambda の中で手続き的な書き方をする - IT戦記
クラス
class Counter(object): def __init__(self): self.__count = 0 def count_up(self): self.__count =+ 1 print self.__count counter = Counter() counter.count_up()
- self がいわゆる this。
- インスタンス化するときに new つけちゃダメ。
- 先頭に __ を付けると private になる。
- インスタンス変数の宣言・初期化はコンストラクタ(__init__)で行う。
クラスにプロパティを定義する
class Person(object): def __init__(self): self.__name = None @property def name(self): return self.__name @name.setter def name(self, value): self.__name = value
ReadOnly にしたいだけなら @property だけでいいし、単なるgetter/setterであれば、そもそもプロパティでなくて、__init__ で public 変数として宣言しとくだけで良いかな。
class Person(object): def __init__(self): self.name = None
クラスを継承する
そのうち書く
特殊メソッド
そのうち書く
例外処理
そのうち書く
モジュールのインクルード
import time from System import *
- IronPythonでは.NET Frameworkのクラスライブラリも普通にimportできる。
- import foo だと foo.bar のようにアクセスしないといけないけど、from foo import bar のように書くと、bar でアクセスできる。
とりあえず import clr しとく
- これにより、IronPython が封印されし力を全て解放することができるのだ・・っ!
- 具体的には " a ".Trim() とかできるようになる
.NET Framework のDLL(アセンブリ)を読み込む
- アセンブリ読み込むときはclr.AddReference()
.NET Framework のクラスライブラリの引数に byte[] やら string[] を渡す
import System bytes = (0x00, 0x88, 0xff) print System.Convert.ToBase64String(bytes)
タプルを使うとおk。
C# でいうところの byte[2048] buff = new byte[2048];
import System
buff = System.Array.CreateInstance(System.Byte, 2048)
リフレクションで無理やりな感じに作る。
ジェネリック型を使う
from System.Collections.Generic import * data = List[int]() data.Add(1)
sys._getframe() を使えるようにする
ipy.exe のコマンドラインオプションに -X:Frames か -X:FullFrames を付ける。IronPython 2.6 から付いたオプションで、デフォルトでは無効になっている。