2013-07-23 52 views
0

我已经编写了一个Python库,它的函数调用中使用了大量的命名参数,我想知道是否有任何方法可以自动删除所有这些命名参数手动删除它们(这是一项非常单调的任务)。自动从Python函数调用中删除命名参数

例如,才有可能把这种函数调用:(?它省略了命名参数,并且更加简洁)

getClass(lang="Java", body=[ 
    mainMethod(lang="Java", body=[ 
     println(lang="Java", toPrint="Hello World") 
    ]) 
]) 

到下面的函数调用:

getClass("Java", [ 
    mainMethod("Java", [ 
     println("Java", "Hello World!") 
    ]) 
]) 

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

+1

你可以尝试在你的编辑器中使用搜索和替换。但请注意,这两者并不总是相同的。如果'getClass'的关键字参数没有按顺序传递,或者'getClass'接受'** kwargs',则第二种形式可能无效。您是否可以安全地做到这一点取决于功能签名。 – BrenBarn

+3

为什么这样做是可取的?你想解决什么问题?引用python的禅宗,_“明确比隐含”更好。 – Eric

+0

@Eric关键字参数通常对于确保语义清晰度(尤其是对于需要很多参数的函数)非常有用,但在某些情况下我已经过度使用它们,并且我想从几个函数调用中移除关键字参数,以便保持简洁。 (换句话说,它们对于维护代码可读性非常有用,除非它们被过度使用)。 –

回答

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) 

思考它,你的例子似乎想这将授予此行为的任何功能的普通函数 - 递归。这里有一个方法来做到这一点,利用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))) 

如果你不是很长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) 

适应这个对你的代码,现在,会要求你写的代码,会变成你的函数调用之前将泛音评估他们。这取决于你想从这个角度做什么 - 我想不出一个聪明的方法来解决这个事实,功能调用传递参数之前,它们被传递,因为这会干扰你是什么试图去做。

相关问题