Python 3000の新機能についてお知らせする連載も3回目。今回は言語仕様,組み込み関数,クラスへの変更などについての変更点についてまとめています。
http://gihyo.jp/dev/feature/01/python3000/0003
Python 3000では,一貫性を増すための仕様変更だけでなく,言語をより便利にする変更も多く行われています。
Function Annotations(関数注記)はおもしろいですね。関数につけるドキュメント文字列のように,引数や返り値にドキュメンテーションを加えることができる機能です。引数の後にコロンをつけて,文字列を表記します。
def func(arg1:"this arg is for brabra"): ...
コロンのあとはPythonの式として評価されます。文字列リテラルだけでなく,Pythonの式ならなんでも置くことができます。コロンの後は関数オブジェクトが持つアトリビュートに,引数をキーとした辞書として格納されます。
このことを利用すると,引数の型チェックを手軽に実行できます。たとえば,引数の型を制限するために,型オブジェクトを指定するとします。こんな感じ。
def func(arg1:int, arg2:str): ...
このような関数と,以下のように定義したargcheckをデコレータとして組み合わせると,引数の型チェックが行えます。関数定義の直前に「@argcheck」と書いておくわけですね。
#!/usr/bin/env python3.0 import inspect def getargvalue(fargs, argname, in_args, in_kwargs): """ 関数の引数リストを受け取り,引数名から与えられた引数を得る """ # まずキーワード引数に与えられた引き数名があるかしらべ,あったら返す if argname in in_kwargs: return in_kwargs[argname] # 得た関数名を使って引数を調べる if argname in fargs: regdict=dict(zip(fargs, in_args)) if argname in regdict: return regdict[argname] # TODO:デフォルト引数,Keyword only argumentなどについて対応する raise ValueError("no such argument: %s" % argname) def argcheck(func): """ Python 3.0から追加されたFunction Annotationsを使い キーワードの型を調べるデコレータ """ # 引数として受け取った関数オブジェクトを関数ローカルな変数に保存 func=func # getfullargspecを使って関数に定義された引数のリストなどを得る (fargs, fvarargs, fvarkw, fdefaults, fkwonlyargs, fkwonlydefaults, fannotations)=inspect.getfullargspec(func) def checkarguments(*in_args, **in_kwargs): """ 引数をチェックして指定された型かどうかを調べる 型が違ったら例外を発生,すべての引数の型があっていたら関数を呼び出す """ for name in fargs: # 引き数名から引数を得る v=getargvalue(fargs, name, in_args, in_kwargs) # annotationsに記載された型指定を得る t=fannotations[name] if not isinstance(v, t): raise ValueError("The argument '%s' for function '%s'" "should be %s" % (name, func.__name__, t)) func(*in_args, **in_kwargs) return checkarguments if __name__ == '__main__': @argcheck def some_func(arg1:int, arg2:str): """ テスト用の関数 """ print("some_func : arg1=%s, arg2=%s" % (arg1, arg2)) # これはOK some_func(1, "2") # 例外が出る,なぜなら2番目の引数が求められているstrでなくintだから some_func(1, 2)
もちろん,このコードはPython 3.0でしか動きません。 関数定義の仕様には,Function Annotationsの他にKeyword only argumentsなども追加されています。これにあわせて,inspectモジュールにもいくつか関数が追加されています。
深く見てみると,Python 3.0はすごく面白いですね。リリースがとても楽しみです:-)。