IronPythonリハビリメモ

ここ1年以上、VB.NETJavaScriptC#XAMLしか書いてなかったので、IronPython(というかPython自体)をほとんど忘れてしまっていた。なので未来の自分が読んだらコードが書ける程度にメモを残しとく。

一日で書けるやろ…ぐらいで書いてたら意外と終わらなかったので、これから少しずつチマチマ追記していく予定。

Hello World

print "こんにちわ せかい"

IronPython では CPython とは違って、マルチバイト文字列であっても、u"こんにちわ せかい"みたいに u つけなくていい。

スクリプトファイルの文字エンコーディング指定

スクリプトの先頭にこんなの書いておく。

# -*- coding: utf-8 -*-

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

ググってたらC#風に書く方法も見つけたけど、バッドノウハウ臭がプンプンするのでやめといた方がよさそう。
はてなダイアリー

クラスを継承する

そのうち書く

特殊メソッド

そのうち書く

例外処理

そのうち書く

モジュールのインクルード

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 から付いたオプションで、デフォルトでは無効になっている。