记录/修饰Python函数/方法的最佳方法是什么,以便您能够通过签名轻松查询它们(例如参数计数,参数类型和返回类型)?
我正在使用遗传编程包,我想扩展它,以便能够动态替换表达式中的函数,方法是使用等效签名从模块中的所有函数中随机选择替换。
我正在考虑滚动自己的装饰器,所以我可以做类似的事情:
@validate(args=((int, range(1,10), (float, range(1,10)), (bool,)), returns=(int,range(-10,10))
def myfunc(a, b, c):
result = do_stuff
return result
然后能够通过执行以下操作来查询类似的函数:
similar_functions = find_functions(like=myfunc)
这条线上是否有任何标准工具或库?
答案 0 :(得分:2)
您可以使用inspect
获取函数的参数列表。这包括默认值,但当然不能提供类型,因为这些定义缺少此信息。
如果您需要类型信息,那么您所展示的装饰者似乎是2.x的最佳解决方案。但我可能会使他们的语法不那么括号:
@validate(a=(int, 1, 10), b=(float, 1, 10), c=bool, returns=(int, -10, 10))
def foo(a, b, c): ...
如果装饰器实际检查函数的arglist并确保它与装饰器的参数匹配,则可能会检测到明显的错误。如果您不打算添加验证代码,则无需修改实际功能。
请注意,您需要对*arg
和**kwarg
进行特殊处理:提供类型信息要困难得多,而且我不知道f1(int, int, int)
类似于f2(int, *ints)
,更不用说f3(int, **kwargs)
。
答案 1 :(得分:2)
为了与“我们都是成年人”的心态保持一致,为什么需要确保实际遵守指定的类型? 你知道函数的签名是什么意思,所以只需用装饰器标记每个函数并将标签存储在字典中。
>>> import collections
>>> tags = collections.defaultdict(set)
>>>
>>> def tag(tag):
... def decorator(func):
... tags[tag].add(func)
... func.tag = tag
... return func
... return decorator
...
>>> @tag("foo")
... def a(): pass
...
>>> @tag("foo")
... def b(): pass
...
>>> tags['foo']
{<function b at 0x0000000002BF2448>, <function a at 0x0000000002BD5A48>}
similar
是微不足道的:
def similar(func):
return signatures[func.sig]
答案 2 :(得分:0)
通过使用等效签名从模块中的所有函数中随机选择替换,动态替换表达式中的函数。
就这样做。
all_functions_of_some_sig = [
myfunc, myfunc2, myotherfunc, ...
]
这并不难。并且它更有可能工作,因为任何过滤或匹配都将由函数的设计者完成。
这可能更简单
def myfunc( a, b, c ):
return something
myfunc.args= ((int, range(1,10), (float, range(1,10)), (bool,))
myfunc.returns= (int,range(-10,10))
patterns= collections.defaultdict( list )
for f in __all__:
patterns[f.args,f.returns]= f
这就是你想要的吗?
然后,您需要确保__all__
列出所有相关功能。不难做到,并且通常期望包含数千个函数的模块。