我编写了一个Python库,在其函数调用中使用了很多命名参数,我想知道是否有任何方法可以自动删除所有这些命名参数,而不是手动删除它们(这是一个非常繁琐的任务)。
例如,是否可以翻译此函数调用:
getClass(lang="Java", body=[
mainMethod(lang="Java", body=[
println(lang="Java", toPrint="Hello World")
])
])
进入下面的函数调用(省略了命名参数,并且更简洁?):
getClass("Java", [
mainMethod("Java", [
println("Java", "Hello World!")
])
])
为了做到这一点,一种可能的方法是编写一个函数,将其自己的函数调用打印为字符串 - 但是,我不认为编写一个可以执行此操作的函数。还有其他方法可以解决这个问题吗?
答案 0 :(得分:4)
没有必要。关键字参数仍然可以在位置上传递。如果你愿意的话,这里有一个额外的好处,就是能够指定一个或不指定它们。但是,您根本不需要指定任何内容。
>>> def foo(bar=1, baz=[2,3]):
... print bar, baz
...
>>> foo()
1 [2, 3]
>>> foo(baz=4)
1 4
>>> foo(10, 20)
10 20
如果我误解了您提供的代码,请告诉我。史蒂夫的回答似乎表明你实际上正在使用字符串,但我没有在你的帖子中看到任何表明这一点。
你确实提到了一个打印自己的函数调用的函数;通过这个,我假设你的意思是函数必须打印一个字符串,它看起来与你输入的函数一样,用你传递的相同参数调用函数。这相对容易,因为您可以按原样键入函数的名称,也可以使用其__name__
属性。
>>> def goo(a,b):
... print "{}({}, {})".format(goo.__name__, a, b)
...
>>> goo(1,2)
goo(1, 2)
>>> def hoo(*args):
... print "{}({})".format(hoo.__name__, ', '.join((str(arg) for arg in args)))
...
>>>
>>> hoo(2,3,4,5)
hoo(2, 3, 4, 5)
考虑到这一点,你的例子似乎想要一个通用函数,它会将这种行为授予任何函数 - 递归。这是使用partial
s实现这一目标的方法(我将重新定义foo()
,以便示例更有意义):
>>> from functools import partial
>>> def foo(a, b):
... return (a if not isinstance(a, partial) else a()) + (b if not isinstance(b, partial) else b())
...
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> fun()
15
>>> fun = partial(foo, 1, partial(foo, partial(foo, 2, 4), partial(foo, 3, 5)))
>>> def print_pfunc(pfunc):
... return "{}({}{}{})".format(pfunc.func.__name__, ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args) if pfunc.args else '', ', ' if pfunc.args and pfunc.keywords else '', ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords) if pfunc.keywords else '')
...
>>> print print_pfunc(fun)
foo(1, foo(foo(2, 4), foo(3, 5)))
如果你不是很长format()
通话的粉丝,这里写出来(只是,这样你就不必花费时间解码我的垃圾)以不同的方式:
def print_pfunc(pfunc):
args = ""
if pfunc.args is not None:
args = ', '.join(str(arg) if not isinstance(arg, partial) else print_pfunc(arg) for arg in pfunc.args)
kwargs = ""
if pfunc.keywords is not None:
kwargs = ', '.join('{}={}'.format(k, v if not isinstance(v, partial) else print_pfunc(v)) for k, v in pfunc.keywords)
return "{}({}{}{})".format(pfunc.func.__name__, args, ', ' if args and kwargs else '', kwargs)
现在,将此修改为代码将要求您编写代码,在评估它们之前将函数调用转换为部分代码。这取决于你想从这个角度做什么 - 我想不出一个聪明的方法来绕过一个事实,即功能的通话的作为参数它们传递之前得到评估通过,因为这会干扰你想要做的事情。