這個問題的來源是在看python中的裝飾器的時候,例子裏給了這樣一段代碼:html
#-*- coding: UTF-8 -*- import time def foo(): print 'in foo()' # 定義一個計時器,傳入一個,並返回另外一個附加了計時功能的方法 def timeit(func): # 定義一個內嵌的包裝函數,給傳入的函數加上計時功能的包裝 def wrapper(): start = time.clock() func() end =time.clock() print 'used:', end - start # 將包裝後的函數返回 return wrapper foo = timeit(foo) foo()
上述代碼實現了一個裝飾器,但沒有處理foo()函數帶參數以及返回值的狀況。爲了改進這段代碼,首先要理解的是python中參數傳遞*和**的問題。python
若是在函數定義時候,按照以下定義的:app
#代碼段1 def foo(*a): pass
或者函數
#代碼段2 def foo(**a): pass
這種定義方法至關與C語言中的不定參數,在定義的時候,函數將被傳入的參數是未知的,運行的時候,代碼段1 的代碼 參數將會一tuple的形式組織起來,傳入函數; 代碼段2 的代碼,參數將會以dictionary的形式傳入.net
*和**除了在定義函數的時候有用,它的另外一個功能就是對tuple和dict進行展開。code
因而咱們即可以利用這個運算符對最開始的代碼進行改進:htm
#-*- coding: UTF-8 -*- import time def foo(a): print ' in foo() %s'%a return 100 def foo2(): print ' in foo2()' return #定義定時器,傳入一個,並返回另外一個附加了計時功能的方法 def timeit(func): #定義一個內嵌的包裝函數,給傳入的函數加上計時的包裝 def wrapper(*args,**args2): ######1######### start = time.clock() res=func(*args,**args2) #########2########### end = time.clock() print 'used:',end - start return res return wrapper a=1 foo = timeit(foo) print foo(a) foo2 = timeit(foo2) foo2()
相比於原代碼,主要更改是標號的兩行。 第一行在函數定義的時候,參數裏添加了一個不定參數,以便接受原函數的參數,第二行利用了*運算符的第二個功能,將參數展開,傳遞給原函數。blog