为Python函数参数提供额外的装饰/元数据有什么好方法?

时间:2010-08-31 16:13:13

标签: python

我们正在考虑使用Python(IronPython,但我认为不相关)为另一个控制设备的应用程序提供一种“宏”支持。

我们想在Python中编写相当简单的函数,这些函数需要一些参数 - 这些函数可能是时间,温度和位置。不同的函数将采用不同的参数,主应用程序将包含用户界面(类似属性网格),允许用户为Python函数参数提供值。

因此,例如,function1可能需要一个时间和一个温度,而function2可能需要一个位置和几次。

我们希望能够从Python代码动态构建用户界面。容易做的事情是在模块中查找函数列表,并(使用inspect.getargspec)获取每个函数的参数列表。

然而,只是一个参数名称列表还不够 - 理想情况下我们希望能够包含关于每个参数的更多信息 - 例如,它是'type'(高级类型 - 时间,温度,等等,而不是语言级别的类型),也许是“友好名称”或描述。

所以,问题是,有什么好的'pythonic'方法可以将这种信息添加到函数中。

我想到的两种可能性是:

  • 对参数使用严格的命名约定,然后从名称中推断出它们的内容(使用getargspec获取)

  • 创建我们自己的docstring元语言(可能只是CSV),并使用docstring作为我们的元数据。

因为Python在构建大型应用程序的脚本中似乎非常流行,所以我认为这是一个常见约定的解决问题,但我无法找到它们。

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

答案 2 :(得分:1)

'pythonic'方法是function annotations

def DoSomething(critical_temp: "temperature", time: "time")
    pass

答案 3 :(得分:0)

对于python 2.x,我喜欢使用docstring

def my_func(txt):
    """{
    "name": "Justin",
    "age"   :15
    }"""
    pass

并且可以使用此代码段自动分配给函数对象

for f in globals():
    if not hasattr(globals()[f], '__call__'):
        continue
    try:
        meta = json.loads(globals()[f].__doc__)
    except:
        continue
    for k, v in meta.items():
        setattr(globals()[f], k, v)