2017-08-05 72 views
1

爲了記錄目的,我嘗試自動捕獲傳遞給函數內部函數的參數並將它們轉換爲arg : value的字典。 我試過inspect.signature()模塊,但它僅與函數的默認輸入,而不是參數傳遞給它如何在字典中捕捉函數的輸入參數

import inspect 

def my_add_func(a, b ,c=3): 
    sig = inspect.signature(my_add_func) 
    print("my_add_func args : {0}".format(sig)) 
    return a + b + c 

if __name__ == '__main__': 
    my_add_func(10, 2, 3) 

輸出提供:

(a, b, c=3) 

而我想有:

{a: 10, b: 2, c:3} 

我該怎麼做?

回答

1

你可以使用signature.bind

import inspect 

def my_add_func(a, b ,c=3): 
    sig = inspect.signature(my_add_func) 
    print("my_add_func args : {0}".format(sig.bind(a, b, c))) # changed here 
    return a + b + c 

if __name__ == '__main__': 
    my_add_func(10, 2, 3) 

這給:

my_add_func args : <BoundArguments (a=10, b=2, c=3)> 

如果你想把它當作一個映射(字典類),您可以訪問BoundArguments.arguments屬性:

>>> sig.bind(a, b, c).arguments 
OrderedDict([('a', 10), ('b', 2), ('c', 3)]) 

甚至將其轉換爲純字典:

>>> dict(sig.bind(a, b, c).arguments)) 
{'a': 10, 'b': 2, 'c': 3} 
+0

按預期工作謝謝,我只是按照@Yuval Ben Ari的建議添加'apply_default()'。另外我發現''locals()'更容易使用。它適合我的情況,因爲我只想在函數的開頭就抓住參數。 – MCMZL

+0

@MCMZL如果你這樣做,直接在函數中檢查你不需要'apply_default()',只有當你試圖從外部檢查一個函數時纔有意思。 – MSeifert

+0

@MCMZL我很高興它的工作,請不要忘記[接受](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)最有幫助的答案:) – MSeifert

0

,如果你想記錄功能的輸入您應使用包裝:

import inspect 

def log_args(func): 
    def log_and_call(*args, **kwargs): 
     sig = inspect.signature(func) 
     bound_args = sig.bind(*args, **kwargs) 
     bound_args.apply_defaults() 
     loggable_args = bound_args.arguments 

     print("Function name: " + func.__name__) 
     for key, val in loggable_args.items(): 
      print(key + " = " + str(val)) 

     return func(*args, **kwargs) 
    return log_and_call 

@log_args 
def do_sum(a, b, c=0): 
    return a + b + c 


x = do_sum(1,b=2) 

這種方式很容易記錄每一個函數調用,並阻止樣板代碼。
請注意,我使用apply_defaults,因此如果未提供不同的值,它將打印默認參數的值。
在這個例子中,我也給出了b的名字,雖然它不是一個默認值的參數,只是爲了顯示它的作品。
您可以用寫入到記錄器或類似的東西來替換打印件。

+1

@MSeifert是的,我用'apply_defaults'。我解釋了爲什麼在編輯 –

+0

時@MSeifert我也沒有轉換爲'dict',所以參數的順序不會丟失。 –

+0

謝謝'apply_default()'確實非常有用。我還發現'locals()'描述[這裏](https://stackoverflow.com/questions/7969949/whats-the-difference-between-globals-locals-and-vars),可以用於我的情況 – MCMZL