2017-10-13 6 views
0

동일한 인수를 함수의 선택적 인수에 전달할 때 불필요한 코드 중복을 방지 할 수있는 방법이 있는지 묻고 싶습니다.동일한 옵션 인수를 여러 함수에 전달할 수 있습니까?

는 희망 아래의 예는 내가 뭘하려고 오전의 좋은 아이디어 제공 : 당신이 볼 수 있듯이, F1 및 F2는 F에 전달 된 ARG1에 차이가

def f(arg1): 
    def g(optional_1=0, optional_2=0, optional_3=0): 
     return arg1+optional_1+optional_2+optional_3 
    return g 

b, c = 2, 3 
f1 = f(1) 
f2 = f(2) 
calc_f1 = f1(optional_2=b, optional_3=c) 
calc_f2 = f2(optional_2=b, optional_3=c) 

을, 그 후 나는 그들을 호출 동일한 선택적 인수에 대해 동일한 변수. 코드가 짧을 때 좋습니다. 그러나 10 개 이상의 선택적 인수가 있으면 불필요하게 길어지고 중복됩니다. 는

optional_variable_pair = #some way to combine them 
calc_f1 = f1(optional_variable_pair) 
calc_f2 = f2(optional_variable_pair) 

같은 그래서 난 더 간결하고 읽기 쉬운 코드를 얻을 할 수 있습니까?

+1

내가 전적으로 귀하의 질문을 이해 모르겠지만, 당신이 플랫 연산자 ('*')를 사용하여 시도? 그것은 당신을 도울지도 모른 ㄴ다는 것을 소리가 난다. – Carcigenicate

+0

이 함수들이 무엇이고 반환 값을 사용하고 있는지에 따라 호출 구문을 줄이기보다는 루프 또는 목록 이해에서 이러한 함수를 호출하는 것이 좋습니다. – user2357112

+0

답장을 보내 주셔서 감사합니다. 나는 *가 튜플이나리스트를 언 패킹하는 데 사용될 수 있음을 이해하지만, 나는 그것들을 각각의 선택적 인자와 연관시킬 필요가 있으며 그것을 달성 할 수 있는지를 모른다. –

답변

0

질문 한 질문에 대답하려면 대답은 예입니다. 키워드 인수를 사용하여 원하는 것을 거의 정확하게 풀 수 있습니다. 내가 제대로 당신의 의도를 읽고 있어요 경우

def f(arg1): 
    def g(optional_1=0, optional_2=0, optional_3=0): 
     return arg1+optional_1+optional_2+optional_3 
    return g 

optional_variable_pair = { 
    'optional_2': 2, 
    'optional_3': 3 
} 

f1 = f(1) 
f2 = f(2) 
calc_f1 = f1(**optional_variable_pair) 
calc_f2 = f2(**optional_variable_pair) 

하지만, 질문의 본질은 함수에 같은 연속적인 인수와 함께 새로운 첫번째 인수를 전달하고자한다. 사용 사례에 따라 래퍼 함수 g이 필요하지 않을 수 있습니다. 첫 번째 인자는 하나씩 증가 계속되면

def f(arg1, *, optional_1=0, optional_2=0, optional_3=0): 
    return optional_1 + optional_2+optional_3 

optional_variable_pair = { 
    'optional_2': 2, 
    'optional_3': 3 
} 

calc_f1 = f(1, **optional_variable_pair) 
calc_f2 = f(2, **optional_variable_pair) 

분명히하는 for 루프 위해서이다. 분명히 optional_1 매개 변수를 사용하지 않는다면 매개 변수를 포함 할 필요가 없습니다. 그러나, 또한, 당신은 숫자 인수를 사용하여 자신을 찾을 경우, 좋은 당신이 정말로 튜플 대신 키워드 풀기의 포장을 풀고 작업을해야 기회가있다 :

def f(*args): 
    return sum(args) 

optional_variable_pair = (2, 3) 

for i in range(1, 3): 
    calc = f(i, *optional_variable_pair) 
    # ...do something with calc... 

당신은 또한뿐만 아니라, functools.partial 연구에 관심이있을 수는있는 래퍼 기능 g의 자리를 대신하고, 허용 할 수 있습니다이 :

import functools 

def f(*args): 
    return sum(args) 

f1 = functools.partial(f, 1) 
f2 = functools.partial(f, 2) 

calc_f1 = f1(2, 3) # = 1 + 2 + 3 = 6 
calc_f2 = f2(2, 3) # = 2 + 2 + 3 = 7 
0

당신은이 목적을 위해 당신이 * 인수와 ** kwargs로 사용할 수있는 기능 argsuments 같은 키 - 값 쌍을 사용

optional_variable_pair = { 
    "optional_1": 1, 
    "optional_2": 2, 
    "optional_3": 3, 
} 
calc_f1 = f1(**optional_variable_pair) 
calc_f2 = f2(**optional_variable_pair) 
1

여러 선택적 인수와 모든 기능이를 조금 냄새 나는 이유는

  1. 많은 조합이 필요하므로 많은 양의 테스트가 필요합니다.
  2. 모든 옵션 때문에 함수는 순환 적 복잡성을 증가시키는 많은 조건과 경로가 있어야합니다.

당신은 개체로 전체 인수 목록을 추출하는 리팩토링을 적용하고 해당 객체의 기능의 작업을 할 수 있습니다. 인수 목록을 설명하고 함수를 사용하는 모든 은유에 맞는 통일 된 이름을 찾을 수 있으면 정말 잘 작동합니다. 함수가 Object의 메서드가되도록 호출을 변환 할 수도 있으므로 캡슐화를 얻을 수 있습니다.

+0

'plt.plot()'에 대한 의견은 어떻습니까? 그것은 많은 매개 변수를 가지고 있지만 괜찮다고 생각합니다. 그리고 객체를 함수로 전달한다는 측면에서, 그것은 저와 같은 것입니다. – Reti43

+0

문서를 간략하게 살펴본 결과 꽤 냄새라고 생각합니다. 또한 정보에 입각 한 판단을 내리기 위해 도메인에 대해 충분히 알지 못한다고 생각합니다. 냄새의 요점은, 그들이 당신에게 뭔가 잘못되었다고 말하는 것이 아니라, 당신에게 뭔가 잘못되었다고 말할 수 있습니다. 아마도 plt.plot의 영역에는 기능을 표현하는 명확한 방법이 없습니다. – diabolist