繁体   English   中英

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

[英]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.getargspecinspect.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM