2016-07-15 2 views
2

Мне нужно многократно вызвать многопараметрическую функцию, пока фиксирован только один параметр. Я думал об использовании декораторов:Настройка параметров с помощью декораторов и вложенных функций

# V1 - with @decorator 
def dec_adder(num): 
    def wrap(fun): 
     def wrapped_fun(n1): 
      return fun(n1, second_num=num) 
     return wrapped_fun 
    return wrap 

@dec_adder(2) 
def adder(first_num, second_num): 
    return first_num + second_num 

print adder(5) 
>>> 7 

Но это кажется запутанным, так как это, кажется, вызова функции с 2-параметра, adder только один аргумент.

Другого подход заключается в использовании вложенного определения функции, которая использует локальные переменную от родительской функции:

# V2 - without @decorator 
def add_wrapper(num): 
    def wrapped_adder(num_2): 
     return num + num_2 
    return wrapped_adder 

adder = add_wrapper(2) 
print adder(5) 
>>> 7 

Но я не решаюсь использовать этот подход, так как в моей фактической реализации обернутого функция очень сложен. Мой инстинкт заключается в том, что он должен иметь автономное определение.

Простите меня, если это вступит в сферу мнений, но либо подход считается лучшим дизайном и/или более Pythonic? Есть ли другой подход, который я должен рассмотреть?

ответ

2

functools.partial должен работать хорошо в этом случае:

from functools import partial 

def adder(n1, n2): 
    return n1 + n2 

adder_2 = partial(adder, 2) 

adder_2(5) 

Его строка документации:

частичные (функ, * ARGS ** ключевые слова) - новая функция с частичным применением данности аргументы и ключевые слова.

- так что вы также можете задать аргументы ключевого слова.

PS

К сожалению, встроенный sum не устраивает этот случай: он подводит над итератора (на самом деле, sum(iterable[, start]) -> value), так partial(sum, 2) не работает.

+0

Это хороший и чистый. Спасибо. – andrew

2

Другое возможное решение - вы можете использовать functools и параметризованную декоратора:

from functools import wraps 

def decorator(num): 
    def decor(f): 
     @wraps(f) 
     def wrapper(n,*args,**kwargs): 
      return f(n+num,*args,**kwargs) 
     return wrapper 
    return decor 


@decorator(num=2) # number to add to the parameter 
def test(n,*args,**kwargs): 
    print n 


test(10) # base amount - prints 12 
Смежные вопросы