动态定义具有不同签名的函数

时间:2012-08-14 14:05:04

标签: python dynamic

我想要完成的事情:

dct = {'foo':0, 'bar':1, 'baz':2}
def func(**dct):
    pass
#function signature is now func(foo=0, bar=1, baz=2)

但是,**语法在扩展dict(我想做的事情)和声明一个包含关键字参数的参数(我不想做的事情)之间明显发生冲突。

这可能吗?

3 个答案:

答案 0 :(得分:5)

根据我对您的要求的解释 - 您希望动态定义一个函数,其签名与运行时提供的dict的内容相匹配 - 这里有两个问题使得它不切实际。

  1. 如果参数是在运行时定义的,那么你的函数如何引用变量?您是否计划在运行时构建函数体?
  2. dict s是无序的,因此您无法可靠地使用它们来定义位置参数
  3. 我怀疑这是XY problem。如果你能解释你想要达到的目标,那么也许我们可以提供更好的帮助。

    但是,假设您尝试使用dict分配默认关键字参数,那么实现此目的的一种方法是使用decorators。例如:

    def defaultArgs(default_kw):
        "decorator to assign default kwargs"
        def wrap(f):
            def wrapped_f(**kwargs):
                kw = {}
                kw.update(default_kw)  # apply defaults
                kw.update(kwargs)  # apply from input args
                f(**kw)  # run actual function with updated kwargs
            return wrapped_f
        return wrap
    

    然后,您可以使用此装饰器将默认关键字参数分配给仅需要关键字参数的函数:

    defaults = {'foo':0, 'bar':1, 'baz':2}
    
    @defaultArgs(defaults)
    def func(**kwargs):
        print kwargs  # args accessible via the kwargs dict
    

    结果:

    func()  # prints {'baz': 2, 'foo': 0, 'bar': 1}
    func(foo=2)  # prints {'baz': 2, 'foo': 2, 'bar': 1}
    
    params = {'bar':1000, 'hello':'world'}
    func(**params)  # prints {'baz': 2, 'foo': 0, 'bar': 1000, 'hello': 'world'}
    

    请注意,您将无法使用位置参数:

    func(1, 2, 3)   # raises TypeError
    

答案 1 :(得分:0)

你想要的是eval() link

我给出了类似问题的回答:https://stackoverflow.com/a/11865190/1561176

答案 2 :(得分:0)

我真的不确定你打算在这里完成什么。以下作品(有点):

def func(**dct):
    pass

dct = {'foo':0, 'bar':1, 'baz':2}
func(**dct)

如果动态创建函数,您如何计划在函数中使用foobarbaz?如果你提供一些关于你实际想要完成的事情的更多细节,我们可能会更有帮助。