부분 은 매우 유용합니다.
예를 들어, '파이프 라이닝 된'함수 호출 순서 (한 함수에서 반환 된 값이 다음 함수로 전달되는 인수)
때때로 이러한 파이프 라인의 함수에는 단일 인수 가 필요 하지만이 함수에서 즉시 업스트림 함수는 두 개의 값을 반환 합니다 .
이 시나리오에서는이 functools.partial
기능 파이프 라인을 그대로 유지할 수 있습니다.
다음은 구체적이고 격리 된 예입니다. 일부 대상에서 각 데이터 포인트의 거리를 기준으로 일부 데이터를 정렬한다고 가정합니다.
# create some data
import random as RND
fnx = lambda: RND.randint(0, 10)
data = [ (fnx(), fnx()) for c in range(10) ]
target = (2, 4)
import math
def euclid_dist(v1, v2):
x1, y1 = v1
x2, y2 = v2
return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
이 데이터를 대상과의 거리를 기준으로 정렬하려면 다음과 같이하십시오.
data.sort(key=euclid_dist)
그러나 정렬 방법의 주요 매개 변수는 단일 인수 를 취하는 함수 만 허용합니다 .
따라서 단일 매개 변수 euclid_dist
를 사용하는 함수로 다시 작성하십시오 .
from functools import partial
p_euclid_dist = partial(euclid_dist, target)
p_euclid_dist
이제 단일 인수를 허용합니다.
>>> p_euclid_dist((3, 3))
1.4142135623730951
이제 sort 메소드의 주요 인수에 대한 부분 함수를 전달하여 데이터를 정렬 할 수 있습니다.
data.sort(key=p_euclid_dist)
# verify that it works:
for p in data:
print(round(p_euclid_dist(p), 3))
1.0
2.236
2.236
3.606
4.243
5.0
5.831
6.325
7.071
8.602
또는 예를 들어 함수의 인수 중 하나가 외부 루프에서 변경되지만 내부 루프에서 반복하는 동안 고정됩니다. 부분 (partial)을 사용하면 수정 된 (부분) 함수가 필요하지 않기 때문에 내부 루프를 반복하는 동안 추가 매개 변수를 전달할 필요가 없습니다.
>>> from functools import partial
>>> def fnx(a, b, c):
return a + b + c
>>> fnx(3, 4, 5)
12
키워드 arg를 사용하여 부분 함수 만들기
>>> pfnx = partial(fnx, a=12)
>>> pfnx(b=4, c=5)
21
위치 인수를 사용하여 부분 함수를 만들 수도 있습니다
>>> pfnx = partial(fnx, 12)
>>> pfnx(4, 5)
21
그러나 이것은 던질 것입니다 (예 : 키워드 인수로 부분을 만든 다음 위치 인수를 사용하여 호출)
>>> pfnx = partial(fnx, a=12)
>>> pfnx(4, 5)
Traceback (most recent call last):
File "<pyshell#80>", line 1, in <module>
pfnx(4, 5)
TypeError: fnx() got multiple values for keyword argument 'a'
또 다른 사용 사례 : 파이썬 multiprocessing
라이브러리를 사용하여 분산 코드 작성 . 프로세스 풀은 풀 메소드를 사용하여 작성됩니다.
>>> import multiprocessing as MP
>>> # create a process pool:
>>> ppool = MP.Pool()
Pool
map 메소드가 있지만 단일 iterable 만 필요하므로 더 긴 매개 변수 목록이있는 함수를 전달 해야하는 경우 함수를 부분적으로 재정 의하여 하나를 제외한 모든 것을 수정하십시오.
>>> ppool.map(pfnx, [4, 6, 7, 8])
extra_args
변수를