从python中带有**kwargs的函数中获取带有*args的函数
在Python中,我希望有一个从旧函数构建新函数的方法 输入:一个类似于从python中带有**kwargs的函数中获取带有*args的函数,python,function,arguments,Python,Function,Arguments,在Python中,我希望有一个从旧函数构建新函数的方法 输入:一个类似于f(**kwargs)的函数,以及一个接受关键字字典的成对元组 输出:一个新函数,它将元组中的对作为参数和默认值 到目前为止,我所拥有的: def f(**kwargs): return 'test',kwargs['a'], kwargs['b'] def magic(f,argtuple): arglist=",".join([str(ke)+" = "+str(va) for ke,va in ar
f(**kwargs)
的函数,以及一个接受关键字字典的成对元组
输出:一个新函数,它将元组中的对作为参数和默认值
到目前为止,我所拥有的:
def f(**kwargs):
return 'test',kwargs['a'], kwargs['b']
def magic(f,argtuple):
arglist=",".join([str(ke)+" = "+str(va) for ke,va in argtuple])
keylist=",".join([str(ke)+" = "+str(ke) for ke,va in argtuple])
exec("def g("+arglist+"): return f("+keylist+")")
return g
它符合我的要求:
In [25]: f(b=4,a=3)
Out[25]: ('test', 3, 4)
In [26]: g=magic(f,(['a',1],['b',2]))
In [27]: g()
Out[27]: ('test', 1, 2)
In [28]: g(a=3,b=5)
Out[28]: ('test', 3, 5)
In [29]: import inspect
In [30]: print inspect.getargspec(f)
ArgSpec(args=[], varargs=None, keywords='kwargs', defaults=None)
In [31]: print inspect.getargspec(g)
ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=(1, 2))
但是,我不想构建字符串,也不想使用
exec
函数。实现这一目标的其他方法有哪些?您正在寻找的是
这里有一个解决方案,它也构造了正确的签名。它需要一个合理的最新Python,因为它使用了
inspect
模块中相对较新的添加项以及\uuuu签名\uuu
特殊属性
import inspect
def build_sig(arg_tuple):
return inspect.Signature(parameters = [inspect.Parameter(
name=name, kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
default=default) for name, default in arg_tuple])
def wrap(f, arg_tuple):
sig = build_sig(arg_tuple)
def g(*args, **kwds):
bound = sig.bind(*args, **kwds)
bound.apply_defaults()
return f(**bound.arguments)
g.__signature__ = sig
return g
def f(*args, **kwds):
return(args, kwds)
g = wrap(f, (['a', 1], ['b', 7]))
print(inspect.getargspec(g))
print(g(3))
# ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=(1, 7))
# ((), {'a': 3, 'b': 7})
g
一定要有那个签名吗?或者如果它接受了*args
和**kwargs
,那就没问题了?@Rawing:我想得到所描述的签名解决方案中的对象g
不是函数是的,但它是可调用的<代码>>>>可调用(g)True根据duck键入原则,使用它来代替函数是非常好的。这不是我想要的。例如,对于这个可调用的东西,制表符完成不起作用。
import inspect
def build_sig(arg_tuple):
return inspect.Signature(parameters = [inspect.Parameter(
name=name, kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
default=default) for name, default in arg_tuple])
def wrap(f, arg_tuple):
sig = build_sig(arg_tuple)
def g(*args, **kwds):
bound = sig.bind(*args, **kwds)
bound.apply_defaults()
return f(**bound.arguments)
g.__signature__ = sig
return g
def f(*args, **kwds):
return(args, kwds)
g = wrap(f, (['a', 1], ['b', 7]))
print(inspect.getargspec(g))
print(g(3))
# ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=(1, 7))
# ((), {'a': 3, 'b': 7})