단선 기능으로 구성된 데이터 뭉침 파이프 라인에 대한 단위 테스트 아닙니다 부작용이있다 제안 된 솔루션으로 익명

Mary Rose Cook의 실용적인 프로그래밍 실습 소개를 읽고 반 패턴의 예를 들었습니다.

def format_bands(bands):
    for band in bands:
        band['country'] = 'Canada'
        band['name'] = band['name'].replace('.', '')
        band['name'] = band['name'].title()

이후

  • 이 함수는 하나 이상의 일을한다
  • 그 이름은 설명이 아닙니다
  • 부작용이있다

제안 된 솔루션으로 익명 기능을 파이프 라이닝 할 것을 제안합니다.

pipeline_each(bands, [call(lambda x: 'Canada', 'country'),
                      call(lambda x: x.replace('.', ''), 'name'),
                      call(str.title, 'name')])

그러나 이것은 나에게 덜 테스트 가능한 단점을 가지고있는 것 같습니다. 적어도 format_bands는 단위 테스트를 통해 의도 된 기능을 수행하는지 확인하지만 파이프 라인을 테스트하는 방법은 무엇입니까? 아니면 익명 함수는 설명이 필요 없으므로 테스트 할 필요가 없다는 생각입니까?

내 실제 응용 프로그램은 내 pandas코드를보다 기능적 으로 만들려고 합니다. 종종 “munging”함수 안에 일종의 파이프 라인이 있습니다.

def munge_data(df)
     df['name'] = df['name'].str.lower()
     df = df.drop_duplicates()
     return df

또는 파이프 라인 스타일로 다시 작성하십시오.

def munge_data(df)
    munged = (df.assign(lambda x: x['name'].str.lower()
                .drop_duplicates())
    return munged

이런 상황에서 모범 사례에 대한 제안 사항이 있습니까?



답변

책의 올바른 예에서 더 중요한 부분을 놓친 것 같습니다. 코드의 근본적인 변화는 목록의 모든 값에서 작동하는 방법에서 하나의 요소로 작동하는 것입니다.

목록의 모든 요소에 대해 지정된 작업을 수행하는 iter(이 경우 pipeline_foreach) 와 같은 함수가 이미 있습니다 . for루프 로 복제 할 필요가 없었습니다 . 또한 잘 알려진 목록 작업을 사용하면 의도가 명확 해집니다. map당신 과 함께 값을 변환하고 있습니다. 와 iter각 요소와 부작용을 수행하고 있습니다. for루프를 사용하면 … 글쎄, 당신은 그것을 통해 볼 때까지 정말로 모른다.

수정 된 코드 예제는 여전히 잘 작동하지 않습니다. (알 수있는 한) 목록의 값을 반환하지 않고 변경하여 추가 배관 또는 기능 구성을 방지하기 때문입니다. 기능적으로 선호되는 방법 map은 업데이트 된 country및 로 밴드 목록을 새로 만듭니다 name. 그런 다음 해당 출력을 다음 기능으로 파이프하거나 map밴드 목록을 취하는 다른 기능으로 구성 할 수 있습니다. 을 사용하면 iter파이프 라인 막 다른 골목과 같습니다.

최종 결과 코드에는 테스트를 귀찮게하기에는 너무 작은 작은 기능이 있다고 생각합니다. 결국, replace또는 에 대해 단위 테스트를 작성할 필요가 없습니다 title. 이제 이것들을 자신의 기능으로 구성하고 단일 항목에서 원하는 조합이 달성되는지 단위 테스트 할 수 있습니다. 나 자신, 나는 아마 변경 한 것 format_bands으로 format_band단일 루프의 하락, 그리고라고 pipeline_each(bands, format_band). 그런 다음 format_band를 테스트하여 무언가를 잊지 않았는지 확인할 수 있습니다.

어쨌든, 당신의 코드에. 두 번째 코드 예제는 더 파이프 라인처럼 보입니다. 그러나 이것만으로는 함수형 프로그래밍의 이점을 제공하지 않습니다. 실제로 기능 프로그래밍은 입력 및 출력 측면에서만 호환성을 정의하여 다른 기능과 기능의 호환성을 보장합니다. 함수 내부에 숨겨진 부작용이 있으면 다른 함수와 입력 / 출력이 정렬되어 있어도 런타임까지 호환되는지 알 수 없습니다. 그러나 두 가지 기능에 부작용이없고 입력과 출력이 일치하면 예기치 않은 결과에 대한 걱정없이 파이프 라인을 구성 하거나 구성 할 수 있습니다 .