2013-07-23 95 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) 

適應這個對你的代碼,現在,會要求你寫的代碼,會變成你的函數調用之前將泛音評估他們。這取決於你想從這個角度做什麼 - 我想不出一個聰明的方法來解決這個事實,功能調用傳遞參數之前,它們被傳遞,因爲這會干擾你是什麼試圖去做。

相關問題