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はすごく面白いですね。リリースがとても楽しみです:-)。