Создать новую функцию из существующей с меньшим количеством аргументов - PullRequest
0 голосов
/ 19 января 2020

Я думал, что это сделает мой код проще и легче для чтения, если я смогу сгенерировать новую функцию из существующей, подставив один из ее аргументов. В приведенном ниже MWE я использовал функцию суммирования и попытался реализовать способ, аналогичный декораторам, где a = 5 жестко закодировано в функцию. К сожалению, я не могу правильно интерпретировать трассировку.

def sum(a,b):
    return a+b

foo = sum
print(foo(2,3))

def new_sum(func, *args,**kwargs):
    def wrapper(func, *args,**kwargs):
        x = func(5, *args, **kwargs)
        return x
    return wrapper

bar = new_sum(func=sum)
print(bar(1))

Возвращает:

$ python3 func_arg.py
5
Traceback (most recent call last):
  File "func_arg.py", line 14, in <module>
    print(bar(1))
  File "func_arg.py", line 9, in wrapper
    x = func(5, *args, **kwargs)
TypeError: 'int' object is not callable

1 Ответ

1 голос
/ 19 января 2020

Для этого вы можете использовать functools.partial.

В вашем коде bar совпадает с wrapper, потому что это то, что возвращает new_sum. Когда вы вызываете bar с 1 в качестве аргумента, вы на самом деле вызываете wrapper(1), что невозможно с TypeError: 'int' object is not callable, потому что 1 не вызывается, но вы звоните 1(5, *args, **kwargs) в строке 9.

Ошибка в вашем коде - подпись wrapper. new_sum функция уже принимает func в качестве аргумента, ваш wrapper должен обернуть эту func функцию. Вместо этого вы принимаете func в качестве аргумента для wrapper. Проверьте, как реализовано functools.partial. Читайте также о функциональных декораторах.

...