[英]How can I copy a python function's signature and define a new function?
我想复制一个函数的签名来定义一个新的 function 来扩展它。 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
function 将包含对 ham.spam 中的ham.spam
的任何更改。
前任:
# 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)
要分部分回答您的问题,要获取签名,可以使用inspect模块中的inspect.getargspec
或inspect.getfullargspec
import inspect
fullArgSpec = inspect.getfullargspec(spam)
这回来了
FullArgSpec(args = ['pork','salt','taste'],varargs = None,varkw = None,defaults =(False,),kwonlyargs = [],kwonlydefaults = None,注释= {})
这样,您可以构建参数调用的字符串。 首先建立位置参数,然后建立关键字参数。 简而言之,像这样
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)
此示例通过另一个 function ( fct
) 的 arguments 扩展函数 ( fct_expand_args
) arguments。
import inspect
def fct(a, b=1):
print(a, b)
def fct_expand_args(*args, **kwargs):
full_arg_spec = inspect.getfullargspec(fct)
for kw, arg in zip(full_arg_spec.args, args):
kwargs.update({kw: arg})
print(kwargs)
fct_expand_args(1, 2, c=3) # {'c': 3, 'a': 1, 'b': 2}
fct_expand_args(1, b=2, c=3) # {'b': 2, 'c': 3, 'a': 1}
fct_expand_args(1, d=2, c=3) # {'d': 2, 'c': 3, 'a': 1}
fct_expand_args(e=1, d=2, c=3) # {'e': 1, 'd': 2, 'c': 3}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.