Python的functools模块中有一种函数叫“偏函数”,自从接触它以来,发现确实是一个颇有用且简单的函数,相信你看完这篇文章,你也有相见恨晚的感受。函数
咱们都知道,函数入参能够设置默认值来简化函数调用,而偏函数的做用就是将入参进行默认填充,下降函数使用的难度。编码
如int()函数,能够将字符型转换为整型,且默认的都是以十进制形式来转换,那为何必定是十进制呢?若是想用以二进制的形式转换呢?其实咱们能够看一下int函数它自己的定义spa
能够看到int有两种用法,能够传一个位置参数,还能够多传一个关键字参数base,也就是基于什么格式转换,默认不传base参数是以十进制转换。因此,用二进制形式转换的话只要base=2便可(见下方代码)code
1 value = int('10000') 2 print(value) # 10000
3
4 value = int('10000', base=2) 5 print(value) # 16
若是每次转换的字符串的时候都要输入base参数,显得很麻烦,所以偏函数的做用就体现出来了,可使用functools.partial()函数来从新定义blog
1 from functools import partial 2
3 int2 = partial(int, base=2) 4 res = int2('10000') 5 print(res) # 16
到这里,你应该已经感受到了偏函数的一点点魅力吧,那咱们再从多个角度进一步看透它。ci
1 def add(a, b, c): 2 print('a=',a,'b=',b,'c=',c) 3 return a + b + c 4
5 add10 = partial(add, 10) 6 res = add10(1, 2) # a= 10 b= 1 c= 2
如上代码中,partial(add, 10)入参并无指定哪一个关键字参数,函数却默认的将这个值传给了第一个参数a,那就说明,当没有指定默认参数时,默认赋值给第一个参数,余下参数按位置参数赋值。字符串
1 def sum(*args): 2 s = 0 3 for n in args: 4 s += n 5 return s 6
7 sum10 = partial(sum, 10) 8 print(sum10(1)) # 11
9 print(sum10()) # 10
按上述理解,没有指定默认参数时,默认赋给第一个参数,那么第一个参数永远是10,后面再传入参的话就从第二个参数开始计算,所以会实现10 + 1 = 11 的结果。一样,若是不继续传参的话,只有默认的10,因此结果就是10get
1 D = {'value1':10, 'value2':20} 2 V = {'Default':100} 3 def show(**kw): 4 for k in kw: 5 print(k, kw.get(k)) 6 7 showDef = partial(show, **V) 8 showDef(**D) 9 # Default 100 10 # value1 10 11 # value2 20
同理,此时入参因为是可变参数,所以默认是第一个传入,先打印Default关键字,这里关注一下函数的写法,可变关键字参数要写成(**V)it
1 def student(name, * , age, city): 2 print('name:',name, 'age:',age, 'city:',city) 3
4 studentAge = partial(student, age=20) 5 studentAge('Tom','Beijing') 6 # TypeError: student() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given
咱们知道,当用*号分隔开,表示后面的关键字参数是必传的,所以对于默认参数也是一样适用,即当参数为必传时,偏函数也须要对每一个关键字参数设置默认值。所以修改后为io
1 studentAge = partial(student, age=20, city='Beijing') 2 studentAge('Tom') # name: Tom age: 20 city: Beijing
综上,偏函数能够将目标函数的部分参数固化后,从新定义为新的函数,下降了编码的复杂度,尤为是当参数不少的时候,或者只用到其中某些参数的场景下时,效果更为显著。
到这里,你是否有了相见恨晚的感受呢?简单函数小技巧,很是实用的偏函数用法就介绍完了,若是以为有用,请关注我,后续会继续分享更多好用好知识。