2016-07-21 3 views
1

Мне нужно передать функцию (без ее вызова) на другую функцию, но мне нужно указать другое значение для аргумента по умолчанию.Разбор аргументов по умолчанию в функциях python без выполнения функции

Например:

def func_a(input, default_arg=True): 
    pass 

def func_b(function): 
    pass 

func_b(func_a(default_arg=False)) 

Это, однако, вызывает func_a() и передает результат func_b().

Как установить default_arg=False без выполнения func_a?

+0

Будет 'func_b' только когда-либо передать' input', когда он называет 'func_a', или вы также должны обрабатывать возможность' 'func_b' перекрывая default_arg' тоже. BTW, 'input' не является хорошим выбором имени переменной, поскольку он затеняет встроенную функцию' input'. –

ответ

2

Использование лямбда-функции. Как это:

func_b(lambda input: func_a(input, default_arg=False)) 

В func_b вы будете иметь вызываемую function, который принимает входной аргумент и выполняет func_a с ранее указанным default_arg аргументом.

EDITED:

Благодаря cdarke, кто пытается сказать нам, что есть только один правильный способ сделать это.

from functools import partial, wraps 

def func_wrapper(f, **kwargs): 
    @wraps(f) 
    def wrapper(input): 
     return f(input, **kwargs) 
    return wrapper 

func_b(func_wrapper(func_a, default_arg=False)) 
+1

'lambda' не имеют атрибутов '__name__' или' __doc__'. Мы не знаем, требуется ли какой-либо из них 'func_b'. – cdarke

+0

@cdarke спасибо за ваш комментарий – frist

4

Используйте functools.partial() object:

from functools import partial 

func_b(partial(func_a, default_arg=False)) 

partial() объект является вызываемым тоже, когда называется он будет применять аргументы, которые вы дали его первый аргумент.

Демо:

>>> from functools import partial 
>>> def func_a(input, default_arg=True): 
...  print('func_a() called with {!r}, and default_arg={!r}'.format(input, default_arg)) 
... 
>>> def func_b(function): 
...  print('Calling the function') 
...  function('Foo bar') 
... 
>>> func_b(partial(func_a, default_arg=False)) 
Calling the function 
func_a() called with 'Foo bar', and default_arg=False 
+0

'partial' объекты не имеют атрибутов' __name__' или __doc__'. Мы не знаем, будет ли это проблемой, но это можно облегчить, используя 'functools.update_wrapper()'. – cdarke

+1

@cdarke: вы можете добавить дополнительные атрибуты в 'partial()' instance; однако они не будут использоваться в выводе 'repr()' объекта. –

Смежные вопросы