自动从Python函数调用中删除命名参数

And*_*een 0 python

我已经编写了一个Python库,该库在其函数调用中使用了很多命名参数,我想知道是否有任何方法可以自动删除所有这些命名参数,而不是手动删除(这是非常繁琐的任务) 。

例如,可以翻译此函数调用:

getClass(lang="Java", body=[
    mainMethod(lang="Java", body=[
        println(lang="Java", toPrint="Hello World")
    ])
])
Run Code Online (Sandbox Code Playgroud)

放入下面的函数调用中(它省略了命名参数,并且更加简洁?):

getClass("Java", [
    mainMethod("Java", [
        println("Java", "Hello World!")
    ])
])
Run Code Online (Sandbox Code Playgroud)

为此,一种可能的方法是编写一个将其自身的函数调用打印为字符串的函数-但是,我认为不可能编写执行此操作的函数。是否还有其他方法可以解决此问题?

2rs*_*2ts 5

没有必要。关键字参数仍然可以按位置传递。如果您愿意的话,这里可以指定一个或不指定任何一个,这还有一个额外的好处。但是,您根本不需要指定任何内容。

>>> def foo(bar=1, baz=[2,3]):
...     print bar, baz
... 
>>> foo()
1 [2, 3]
>>> foo(baz=4)
1 4
>>> foo(10, 20)
10 20
Run Code Online (Sandbox Code Playgroud)

如果我误解了您提供的代码,请告诉我。史蒂夫(Steve)的回答似乎表明您实际上正在使用字符串,但是我在您的帖子中没有看到任何表明这一点的东西。

您确实提到了一个函数,该函数会打印其自己的函数调用。这样,我假设您的意思是该函数必须打印一个字符串,该字符串看起来与您键入的内容完全相同,以使用传递的相同参数来调用该函数。这相对容易实现,因为您可以按原样键入函数的名称,也可以使用其__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)
Run Code Online (Sandbox Code Playgroud)

考虑一下,您的示例似乎想要一个通用函数,该函数将这种行为递归授予任何函数。这是使用partials的一种方法(我将重新定义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)))
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢这么长的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)
Run Code Online (Sandbox Code Playgroud)

现在,要对此进行调整以适应您的代码,将需要您编写代码,该代码将在评估它们之前将函数调用转换为局部函数。从现在起,您要根据自己的意愿进行操作-我想不出一种聪明的方法来解决这样一个事实,即在传递参数之前先对传递的函数调用进行赋值,因为这会干扰您尝试执行的操作做。