如何复制python函数的签名并定义新函数?

时间:2016-02-19 18:16:18

标签: python python-3.x

我想复制一个函数的签名来定义一个扩展它的新函数。 Python 3.4,如果版本对解决方案很重要。

ham.py

def spam(pork *, salt, taste=False):
    """External function I don't control."""
    return food

eggs.py

import ham

def breakfast(pork, *, drama, salt, taste=False):
    """The function I want to define, done statically."""
    return eggs, ham.spam(pork=pork, salt=salt, taste=taste)

我想定义breakfast,以便如果用户安装了ham.py的不同但兼容的版本,breakfast函数将包含ham.spam中的参数的任何更改{1}}。

例如:

# Probably not how you do this...
signature = inspect.Signature(breakfast)
breakfast = types.FunctionType(
    how-do-i-make-a-multi-line-code-object, 
    what-do-i-use-for-globals,
    name='breakfast', 
    argdefs=from-signature)

1 个答案:

答案 0 :(得分:0)

要部分回答您的问题,要获得签名,您可以使用inspect模块中的inspect.getargspecinspect.getfullargspec

import inspect
fullArgSpec = inspect.getfullargspec(spam)

返回

  

FullArgSpec(args = ['pork','salt','taste'],varargs = None,varkw = None,defaults =(False,),kwonlyargs = [],kwonlydefaults = None,annotations = {})

有了这个,你可以建立一个参数调用字符串。首先构建postional args然后构建关键字参数。粗略地说,像这样的东西

argumentsString = ""
for argument in itertools.chain(fullArgSpec.args, fullArgSpec.kwonlyargs):
    if argument in locals():
        argumentsString += '{}={},'.format(argument,locals()[argument])

请注意,如果缺少任何位置参数,则可能会失败。如果需要,您应该添加一个支票,以便在此时干净地退出。

对于你想要构建函数的第二部分,我希望找到像apply这样的东西,但它似乎已被弃用了。构建argumentString的原因是使用exec执行此操作以执行对spam的调用,其中构建的参数字符串与正常函数调用匹配

exec('spam({})'.format(argumentsString))

传递给exec的字符串是

  

垃圾邮件(猪肉= 2,盐= 3)