functools即函数工具,functools 模块中主要包含了一些函数装饰器和便捷的功能函数。partial是部分,字面理解funcition.partial模块的意思是函数工具内的部分模块功能。实际上partial的意思是固定原函数的部分参数从而构造一个新的函数,下面举例说明:
from functools import partial
def add(a,b):
print('a:',a,'b:',b,'a+b:',a+b)
print("固定参数a为6:")
add_b = partial(add,6) # 固定参数a
add_b(3)
add_b(5)
'''
add_a = partial(add,a = 2)
add_a(3) >> TypeError: add() got multiple values for argument 'a'
add_a(a = 3) >> TypeError: add() missing 1 required positional argument: 'b'
add_a(a = 3,b = 5) >> a: 3 b: 5 a+b: 8
add_a(b=3) >> a: 2 b: 3 a+b: 5
'''
print("固定参数b为6:")
add_a = partial(add,b = 6) # 固定参数b
add_a(3)
add_a(5)
print("固定参数a,b:")
add_ab = partial(add,3,2) # 固定a,b的值
add_ab()
# add_ab(2,1) TypeError: add() takes 2 positional arguments but 4 were given
输出的结果如下:
固定参数a为6
a: 6 b: 3 a+b: 9
a: 6 b: 5 a+b: 11
固定参数b为6
a: 3 b: 6 a+b: 9
a: 5 b: 6 a+b: 11
固定参数a,b
a: 3 b: 2 a+b: 5
附上partial的源代码:
class partial(Generic[_T]):
func: Callable[..., _T]
args: Tuple[Any, ...]
keywords: Dict[str, Any]
def __init__(self, func: Callable[..., _T], *args: Any, **kwargs: Any) -> None: ...
def __call__(self, *args: Any, **kwargs: Any) -> _T: ...
partial的应用:求多个坐标与点(2,4)之间的欧氏距离(euclidean distance)
import random as RND
from functools import partial
import math
fnx = lambda: RND.randint(0, 10) # 生成一个(0,10)的随机数
data = [ (fnx(), fnx()) for c in range(10) ] # 生成10个随机坐标
target = (2, 4) # 目标的坐标
def euclid_dist(v1, v2): # 计算欧氏距离
x1, y1 = v1
x2, y2 = v2
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
p_euclid_dist = partial(euclid_dist,target) # 固定参数v1后生成新的函数
data.sort(key=p_euclid_dist) # 对欧氏距离进行排序
print(data)
print('-'*30)
for x in data:
print(p_euclid_dist(x))
输出结果如下:
[(5, 5), (0, 7), (2, 0), (5, 8), (8, 5), (6, 9), (8, 0), (9, 2), (9, 6), (9, 10)]
------------------------------
3.1622776601683795
3.605551275463989
4.0
5.0
6.082762530298219
6.4031242374328485
7.211102550927978
7.280109889280518
7.280109889280518
9.219544457292887
参考链接:https://blog.csdn.net/cassiepython/article/details/76653897