如何为Python函数参数提供额外的装饰/元数据?
我们正在考虑使用Python(具体是IronPython,不过我觉得这不是重点)来为另一个应用程序提供一种“宏”支持,这个应用程序控制着一台设备。
我们想用Python写一些比较简单的函数,这些函数会接收一些参数,比如时间、温度和位置。不同的函数会接收不同的参数,而主要的应用程序会有一个用户界面(类似属性网格),让用户可以为Python函数的参数提供值。
举个例子,function1可能需要一个时间和一个温度,而function2可能需要一个位置和几个时间。
我们希望能够根据Python代码动态构建用户界面。比较简单的事情是找到模块中的函数列表,并使用inspect.getargspec来获取每个函数的参数列表。
不过,仅仅有参数名称的列表是不够的——理想情况下,我们希望能包含一些关于每个参数的更多信息,比如它的“类型”(高层次的类型,比如时间、温度等,而不是编程语言中的类型),还有可能的“友好名称”或描述。
所以,问题是,有什么好的“Pythonic”方式来为函数添加这种信息。
我想到的两种可能性是:
使用严格的命名约定来命名参数,然后根据它们的名称推断一些信息(通过getargspec获取名称)
发明我们自己的文档字符串元语言(可能只是简单的CSV)并用文档字符串来存储我们的元数据。
因为Python在大型应用程序中构建脚本方面似乎很受欢迎,我想这个问题应该有一些常见的解决方案和约定,但我还没能找到它们。
4 个回答
1
用“python风格”的方法来做这件事,就是使用函数注解。
def DoSomething(critical_temp: "temperature", time: "time")
pass
4
我会使用某种装饰器:
class TypeProtector(object):
def __init__(self, fun, types):
self.fun, self.types = fun, types
def __call__(self, *args, **kwargs)
# validate args with self.types
pass
# run function
return fun(*args, **kwargs)
def types(*args):
def decorator(fun):
# validate args count with fun parameters count
pass
# return covered function
return TypeProtector(fun, args)
return decorator
@types(Time, Temperature)
def myfunction(foo, bar):
pass
myfunction('21:21', '32C')
print myfunction.types
7
装饰器是一种很好的方式,可以给函数添加一些额外的信息。你可以创建一个装饰器,它接受一个类型列表,然后把这些类型添加到一个叫做 .params 的属性里,或者其他类似的地方:
def takes(*args):
def _takes(fcn):
fcn.params = args
return fcn
return _takes
@takes("time", "temp", "time")
def do_stuff(start_time, average_temp, stop_time):
pass