Home » 레퍼런스 » PYTHON » python partial 함수를 알아봅시다.

python partial 함수를 알아봅시다.

functools에 있는 python partial 함수는 어떤 일을 할까요? 이 글에서 간단하게 알아봅시다.


함수에 대한 설명

먼저, 설명을 보고 간단한 예제를 작성해 보도록 하겠습니다.

[그림 1] 함수에 대한 설명

이 함수는 아래와 같은 인자를 받습니다.

  • __func
  • *args, **kwargs
    • 인자와 키워드 인자들

어떤 것을 돌려주는가? 새로운 함수를 돌려주는데, 넘겨준 arguments와 keywords를 넘겨받은 것을 돌려줍니다. 예제를 하나 보도록 하겠습니다.

[그림 2] 예제 1번 프로그램

foo 함수는 key와 val 인자를 받습니다. 8번째 줄에, python partial 함수를 적용한 결과를 받습니다. 2번째 인자로 val=3을 넘겨주었는데요. 이는 base_foo 에는 인자 val이 3으로 들어간다는 의미입니다. 여기까지 상황을 그려보도록 하겠습니다.

val이 3이라는 정보가 base_foo에 들어갑니다. 이렇게 되면, base_foo에는 key 값만 넘겨주면 됩니다. 9번째 줄에는 key의 값으로 “foo”를 넘겨주었습니다. 이미 base_foo에는 호출할 foo 함수가 인자 val의 값이 3이라는 정보가 있었습니다.

이 정보에, va따라서, base_foo(key=”foo”)를 호출하면, 호출할 함수 foo는 인자 2개를 받는데, key의 값이 “foo”이고, val 값이 3이라는 정보가 완성됩니다. 따라서, 문자열 “foo = 3″이 출력됩니다.

9번째 줄의 base_foo(key=”bar”)가 호출되면 어떤 일이 벌어질까요? foo 함수가 호출되는데, 인자 key의 값이 “bar”로, val의 값이 3으로 넘겨지게 됩니다. 따라서, 문자열 “bar = 3″이 출력됩니다. 예제 1번의 결과는 아래와 같습니다.

[그림 3] 예제 1번의 결과

이렇게 partial 함수는 넘겨주는 인자의 값을 고정 시키기 위해 사용할 수 있습니다.


python partial 함수의 다른 예제

defaultdict 클래스는 __getitem__ 에서 키가 없을 때 키를 생성하기 위한 factory를 넘겨줄 수 있습니다. 자세한 사항은 이 을 참고하세요.

이 글에서는 이를 재귀적으로 구현해 보도록 합니다. 먼저, __getitem__에서 key가 없을 때 0을 리턴하게 하는 defaultdict는 defaultdict(int)를 해 주면 됩니다. depth가 1인 경우입니다. 2인 경우에는 어떻게 해야 할까요? 예제 3번과 같이 하면 됩니다.

[그림 4] 예제 3번 프로그램

이 프로그램은 아래와 같이 동작합니다.

  • 키 3이 없으므로, f가 호출됩니다.
  • defaultdict에서, 키 2가 없으므로 int가 호출됩니다.

depth가 3인 경우에는 어떻게 해야 할까요?

[그림 5] 예제 4번 프로그램

예제 4번과 같이 하면 됩니다. 이 프로그램이 어떻게 동작하는가? 마찬가지로 해석하시면 됩니다.

  • dic에서 3이 없기 때문에, g가 호출됩니다.
  • g는 키가 없을 때 f를 호출하는 defaultdict를 리턴합니다.
  • dic[3]에서 키 2가 없으므로, f가 호출됩니다.
  • dic[3][2]는 defaultdict(int)와 연결됩니다.
  • dic[3][2]에 키 4가 없기 때문에, int가 호출됩니다.

뭔가 복잡한데요. 그림으로 도식화 시키면 아래와 같습니다.

먼저 dic = defaultdict(g)라고 했어요. 3이 dic에 없으면 g가 호출됩니다. 그리고, defaultdict(f)가 리턴될 겁니다. dic[3] = defaultdict(f)가 들어갑니다.

다음에, dic[3]에 키 2가 없습니다. dic[3]에는 factory가 f인 디폴트 딕셔너리가 있었습니다. 3은 있었고, 2가 없습니다. defaultdict(f) 때문에, f가 호출됩니다. f는 factory가 int인 디폴트 딕셔너리를 돌려줍니다.

이제 dic[3][2]에 4가 있는지 볼까요? 없어요. dic[3][2]는 있기 때문에, defaultdict(int)를 가져 옵니다. factory가 int인 경우, 0을 돌려줍니다. 예제 5번에서 함수 g를 보면, return defaultdict(f)와 같이 되어 있습니다. 이를 partial로 변환하면 아래와 같이 됩니다.

  • conv = partial(defaultdict, conv)

이는 1번째 인자가 conv인 defaultdict 함수를 돌려달라는 의미입니다. 이제 아래 6번 예제를 해석해 봅시다.

[그림 7] 예제 6번 프로그램

먼저, 5번째 줄의 conv는 아래를 의미합니다.

  • 함수가 defauldict이고 인자 default_factory가 int인 것.

이 상태에서 dic = conv()를 호출하면, dic는 디폴트 factory가 int인 default_dictionary가 될 겁니다. 그런데, 6번째 줄과 7번째 줄에 아래와 같은 문장이 있습니다.

  • conv = partial(defaultdict, conv)

이 말이 무슨 의미일까요?

__getitem__ 함수에서 __missing__ 이벤트가 발생하였을 때, conv를 호출해서 값을 할당한다는 의미입니다. 따라서, 6번째 줄의 conv와 7번째 줄의 conv는 아래와 같음을 알 수 있습니다.

  • 5번째 줄의 conv는 defaultdict(int), f와 같습니다.
  • 6번째 줄의 conv는 defaultdict(f), g와 같습니다.
  • 7번째 줄의 conv는 defaultdict(g)와 같습니다.

중요한 것은 default_factory가 재귀적으로 정의되었다는 것입니다.

Leave a Comment

10 + 7 =