前天看到了partial的一個新用法,記錄一下顿锰。
概念
函數(shù)聲明如下:
functools.partial(func[,*args][, **keywords])
返回一個可以像函數(shù)一樣被調用的partial實例呛哟,在調用時使用args和keywords參數(shù)。使用python實現(xiàn)時盹沈,類似于:
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
通常的使用方法
通常的用法是在原函數(shù)聲明的參數(shù)中,從前往后連續(xù)將參數(shù)值固定:
>>> from functools import partial
>>> def test_partial(a, b, c, d):
... print a,b,c,d
...
>>> test1 = partial(test_partial,1,2)
>>> test1(3,4)
1 2 3 4
>>> test2 = partial(test_partial,1,2,3,4)
>>> test2(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test_partial() takes exactly 4 arguments (5 given)
這通常只能把前面的參數(shù)固定吃谣,假如有個需求和現(xiàn)有的不一樣乞封,需要使后面的參數(shù)固定,該怎么做岗憋?可以使用下面的方法
新的使用方法
1.使用關鍵字參數(shù)
>>> test3 = partial(test_partial, d=4)
>>> test3(1,2,3)
1 2 3 4
- 其限制
>>> test4 = partial(test_partial, c=3, d=4)
>>> test4(1,2)
1 2 3 4
>>> test5 = partial(test_partial, b=2, d=4)
>>> test5(1,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test_partial() got multiple values for keyword argument 'b'
可以看到肃晚,當只對b和d賦值,然后調用時會報錯仔戈,關鍵值參數(shù)有多個值关串。我們試試在調用時拧廊,使用關鍵字c看看:
>>> test5(1,c=3)
1 2 3 4
可以看出,這樣也可以正常調用晋修。
- 如果對前面的參數(shù)默認賦值吧碾,會出現(xiàn)什么情況?是不是和以前一樣墓卦,只需要使用列表參數(shù)就行了倦春?
>>> test6 = partial(test_partial, a=1,b=3)
>>> test6(3,4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: test_partial() got multiple values for keyword argument 'a'
顯然不行,最后還是得使用關鍵字參數(shù)進行調用落剪。
總結
從上面的運行結果來看溅漾,使用partial規(guī)則如下:
- 將前面連續(xù)的參數(shù)固定,就可以直接繼續(xù)按照原來的參數(shù)繼續(xù)調用著榴。如
>>> test1 = partial(test_partial,1,2)
>>> test1(3,4)
1 2 3 4
- 將后面的連續(xù)參數(shù)固定,就可以直接繼續(xù)使用原來的參數(shù)進行調用屁倔。如
>>> test4 = partial(test_partial, c=3, d=4)
>>> test4(1,2)
1 2 3 4
- 如果默認參數(shù)值不是連續(xù)的或者是直接對前面的連續(xù)參數(shù)賦值脑又,那么就需要使用關鍵字參數(shù)進行調用,如
>>> test5(1,c=3)
1 2 3 4
>>> test6(c=3,d=4)
1 3 3 4