🐍
curve_fitみたいに引数の数を判定して呼べるようにする
Scypiにscipy.optimize.curve_fit
という関数がありますね。この関数はフィッティングしたい関数とx,yのデータを渡してあげると定数を調整して渡した関数にフィッティングしてくれるのですが、なんと関数を渡すだけで引数の個数(ここでは定数の個数)を自動で判定してくれます。このようなプログラムの実装方法を調べてみました。
引数の個数を知る方法
まずは引数の個数を知る方法からです。inspect
モジュールを使います。
import inspect
def foo(a: int, b):
pass
sig = inspect.signature(foo)
for arg in sig.parameters.values():
print(arg.name, arg.annotation)
a <class 'int'>
b <class 'inspect._empty'>
このようにすることで、仮引数名とアノテーションが取得できます。
引数の個数を動的に変える方法
引数の個数を知れても実際に値を渡せなければ意味がありません。実際に値を渡すには以下のようにします。
def foo(a: int, b):
pass
foo(*[1, 1.1])
foo(**{'b': 1.1, 'a': 1})
上記のような方法で、リストや辞書をアンパックして渡すことができます。
まとめ
inspect
モジュールと*
、**
を使うことでcurve_fit
のような関数が実装できました。最後にアノテーションを見ながら引数の数に合わせて関数を呼び出すプログラムをおいておきます。
import inspect
def foo():
print('foo')
def bar(a: int, b, c: float, d: int):
print('bar', a, b, c, d)
def caller(func):
sig = inspect.signature(func)
v = []
for arg in sig.parameters.values():
if arg.annotation == int:
v.append(0)
elif arg.annotation == float:
v.append(0.0)
else:
v.append('Hello')
func(*v)
caller(foo)
caller(bar)
foo
bar 0 Hello 0.0 0
Discussion