2016-07-22 3 views
1

그래서 나는 똑똑하고 DRY 비슷한 기능들로부터 많은 공통 코드를 제거하고 그것들을 한 곳에서 정의 된 도우미 기능으로 바꾸어 놓았다고 생각했습니다. (GitHub diff 참조) 그런 식으로 그들은 모두 한 곳에서 수정할 수 있습니다. 이도우미 함수에서 조기에 반환하는 방법은 무엇입니까?

func_A(stuff): 
    if stuff == guard_condition: 
     return early 
    things = boilerplate + stuff 
    do A-specific stuff(things) 
    return late 

func_b(stuff): 
    if stuff == guard_condition: 
     return early 
    things = boilerplate + stuff 
    do B-specific stuff(things) 
    return late 

그래서 원래

을 (another GitHub diff 참조) 나는

_helper(stuff): 
    if stuff == guard_condition: 
     return early 
    things = boilerplate + stuff 
    return things 

func_A(stuff): 
    things = _helper(stuff) 
    do A-specific stuff(things) 
    return late 

func_B(stuff): 
    things = _helper(stuff) 
    do B-specific stuff(things) 
    return late 

로 변경하지만 나는 그것을 시도하고 깨달았 나는 조기 반환 ("가드"를 이동했기 때문에 ?) 도우미 기능에 그들은 물론 더 이상 작동하지 않았습니다. 이제는 원래 함수에 코드를 추가하여 이러한 문제를 쉽게 처리 할 수 ​​있었지만 복잡성을 다시 개별 함수로 옮기고 반복적으로 반복 할 필요는 없습니다.

이런 상황을 처리하는 가장 우아한 방법은 무엇입니까?

+0

오,이게 데코레이터입니다. – endolith

+0

[가드를 구현하기 위해 파이썬 데코레이터 사용하기] (http://www.siddharta.me/2006/12/using-python-decorators-to-implement.html) – endolith

+0

아,하지만 래핑 할 함수가 다른 수의 인수를 사용하는 경우 , 당신은'* args'를 데코레이터에서 사용할 필요가 있습니다. 그러면 함수 시그니처가됩니다. 이것은 추한 것입니다. – endolith

답변

2

도우미 함수에 전달되는 핵심 기능에 a-specific stuffb-specific stuff을 추출 할 수 있습니다.

_helper(stuff): 
    if guard: 
     return False 
    boilerplate 
    return True 

func_a(stuff): 
    if _helper(): 
     do a-specific stuff 
    return 

func_b(stuff): 
    if _helper(): 
     do b-specific stuff 
    return 
+0

흠, 반환 값이 있습니다. 내 예제를 실제 코드와 비슷하게 만들어야한다고 생각한다. – endolith

+0

같은 원리를 사용할 수있다. 리턴 된 값을, 추가 된 요소가'_helper'가 초기 반환 경로 또는 전체 경로를 거쳤는지 여부와 관계가있는 튜플로 만드십시오. – mtrw

+0

네,하지만 원래의 기능에 복잡성을 더하는 것을 의미하는 것입니다. – endolith

2

: 나는 _helper 반환 값을 줄 것이다 도우미

의 반환 VALS을 이해하기 전에

_helper(stuff, _core_func): 
    if stuff == guard_condition: 
     return early 
    things = boilerplate 
    return _core_func(things) 

_a_core(_things): 
    do a-specific stuff 
    return late 

_b_core(_things): 
    do b-specific stuff 
    return late 

func_A(stuff): 
    return _helper(stuff, _a_core) 

func_B(stuff): 
    return _helper(stuff, _b_core) 

이전 답변 : 그런 다음 도우미는 핵심 함수를 호출할지 여부를 결정합니다 이게 도움이 되나요?

def common_stuff(f): 
    def checked_for_guards(*args, **kwargs): 
     if stuff == guard_condition: 
      return early 
     things = boilerplate 
     else: 
      return f(*args, **kwargs) 
    return checked_for_guards 

@common_stuff 
def func_A(stuff): 
    do A-specific stuff(things) 
    return late 

@common_stuff 
def func_b(stuff): 
    do B-specific stuff(things) 
    return late 
+0

내가 생각하지 못했던 한 가지는 func_A와 func_B가 다른 수의 인수를 사용한다는 것입니다.하지만 이는 래퍼 함수가'* args'를 사용해야 함을 의미합니다.이 함수는 래핑 된 함수의 서명이 될 것입니다. 못생긴, 그래서 나는 다른 솔루션을 사용해야 할 것 같아요. – endolith

+0

위 코드는 func_a와 func_b 모두에 대해 모든 유형 또는 인수에 사용할 수 있습니다. 래핑 된 함수는 func_a 또는 func_b와 같이받은 모든 인수를 전달합니다. – DurgaDatta

관련 문제