2017-10-10 3 views
3
나는 다음과 같은 기능에 기능을 추가하기 위해 요청을받은

: 특히어떻게 플래그에 의해 제어 여러 행동을하는 기능을 분할

def maybe_do_thing(x, y, z, really_do_thing): 
    if really_do_thing: 
    return f(x, y, z) # returns a list 
    return []   # an empty list if we did nothing 

, 또한 추가에 의해 제어, g(x, y, z)를 호출 할 수 있어야한다 깃발. 두 개의 별도의 플래그에 따라, 하나 둘, 둘, 또는 :, F 및 G의 부분 집합이라고 할 수있다

def maybe_do_things(x, y, z, do_f, do_g): 
    results = [] 
    if do_f: 
    results.extend(f(x, y, z)) 
    if do_g: 
    results.extend(g(x, y)) # g needs slightly different params 
    return results 

는 명확하게하려면 명백한 구현입니다. f와 g는 개념적으로 관련되어 있기 때문에 이런 식으로 그룹화하는 것이 합리적입니다. 그러나 실제로는 내게 만족스럽지 않습니다. 실제로 maybe_do_things은 다중 플래그를 사용하여 하나의 함수로 위장한 여러 함수입니다.

나는이 패턴이 반 패턴이지만, 그것이 무엇인지 또는 올바른 패턴이 무엇인지 알지 못한다. 복잡한 함수로 호출하기가 편리하거나 복잡한 함수의 API를 정리하는 방식으로 다중 자체 함수로 나눌 수 있어야한다고 생각합니다. 단지 하나의 큰 얼룩이 아닌 것입니다. .

각 호출 사이트에서 maybe_do_things을 인라이닝하는 것은 그리 좋지 않습니다. 발신자가 f와 g 중 어느 것을 수행 할 것인지 미리 알고 있으면 좋지만 둘 다 런타임에 결정됩니다. 따라서 모든 호출자에게는 현재 반복되는 x/y/z 변수를 나타내는 지역 정의뿐만 아니라 전체 현재 함수 본문이 필요합니다.

나는 앞으로 더 많은 기능이이 기능에 추가 될 것이라고 생각하지 않으므로 적어도 매개 변수 목록이 폭발 할까 걱정하지 않아도됩니다. 아마도 "명백한"구현이 실제로 가장 좋은 절충안일까요?

+0

경우, 이들은하기에 충분한 정보를 가지고 바로 그들 자신에게 전화하십시오. 이 플래그에 대해 더 많이 알지 못하고 함수를 호출하는 위치/방법을 모른 채 분석하기가 약간 어렵습니다. 그러나 한 가지 가능성은'really_do_thing'을'f'를 호출 할 것인가,'context'를 호출 할 것인가 등을 말하는 "플래그"로 생각하는 대신에 가능합니다. 그런 다음 각 호출 사이트는 실제로 수행 할 작업을 결정하는 데 필요한 모든 정보가 들어있는 "컨텍스트"를 전달합니다. 컨텍스트를 메서드로 f, g 등이있는 객체로 만드는 것이 더 좋을 수도 있습니다. – BrenBarn

+0

예, 그들은 올바른 기능을 스스로 호출 할 수있는 충분한 정보를 가지고 있습니다. 하지만 if maybe_do_things 함수에 하나의 부울 인수를 전달하는 것이 훨씬 쉽습니다. 예를 들어, maybe_do_things (..., should_i_do_f())와 같이 if should_i_do_f() : f (x, y, z)의 전체를 쓰는 것보다 훨씬 쉽습니다.)','f'가 복잡한 일이라면. – amalloy

답변

-1

각 함수의 arg 수를 계산할 수 있습니다.

def maybe_do_thing(funcs, *args): 
    res = [] 
    for func in funcs: 
    num_arg = func.func_code.co_argcount 
    new_arg = args[:num_arg] 
    res.append(func(*new_arg)) 
    return res 

def print_f(string): 
    return string + 'a' 

def print_f2(string, string2): 
    return string + 'a' + string2 

print maybe_do_thing([print_f, print_f2], 'd', 'c') 

['da', 'dac'] 
1
나는 기능 maybe_do_things 대신 호출자가 이미 어느 손 전에 전화를 알고 있다면 f(x,y,z) 또는 g(x,y,z)를 호출하는 이유가 무엇인지 이해하지

,하지만 하나의 솔루션은 의사 결정 코드를 구현할 수 도 있으므로 추천 모두 F 또는 g : 4- 가능한 결과와 함수 maybe_do_things 내부 호출자`do_f` 또는`do_g` 합격 여부를 알 수있는 충분한 정보를 갖는

def maybe_do_things(x,y,z, problem): 
    results = [] 
    decision = decide(problem) 
    if decision == 'both': 
     return results.extend(f(x,y,z)+g(x,y)) 
    elif decision == 'neither': 
     return results 
    elif decision == 'f': 
     return results.extend(f(x,y,z)) 
    elif decidion == 'g': 
     return results.extend(g(x,y))