Existe uma maneira de escrever uma função que receba algum parâmetro para modificar várias funções existentes?
Por exemplo, se eu tiver:
def add(a, b):
return a + b
def minus(a, b):
return a - b
def offset_b(func, n):
(??) func(a, b - n)
então quero executar abaixo:
offset_b(add(1, 2), 0.5)
offset_b(minus(1, 2), 0.5)
Eu sei que uma maneira de fazer isso é:
def new_b(b):
return b-0.5
add(1, new_b(b))
minus(1, new_b(b))
Existe uma maneira de usar um wrapper ou algo assim para pegar a função ( add
/ minus
) e n
, para que toda vez que eu inserir alguma, add(1, 2)
ela realmente faça isso add(1, 2 - 0.5)
em vez da versão original?
Defina uma função que aceita uma função existente com parâmetros conhecidos e retorna uma nova função que a encapsula:
Você pode então definir novas versões de
add
eminus
que aplicam o deslocamento:Ou se você quiser criar um decorador adequado para aplicar essa mutação a uma nova função que só deve ser chamada com um deslocamento aplicado, você pode aumentar o aninhamento para produzir um decorador com parâmetros , de modo que a primeira chamada pegue o deslocamento e retorne uma função que, quando chamada com outra função, produza a função encapsulada:
o que permite que você o use como antes, mas em uma ordem diferente:
ou usá-lo como um decorador para modificar a função encapsulada imediatamente:
então
add
eminus
existem imediatamente com o deslocamento de0.5
aplicado a todas as chamadas (confuso neste caso, mas útil em outros).Com a ajuda de @shadowRanger, descobri que há duas maneiras de escrever o wrapper.
Primeira maneira:
Porque eu NÃO TENHO que usar
@offset_b(0.5)
a definição da função before, ooffset_b(n, func)
na verdade pode levarfunc
. Pode economizar uma camada de wrap.Em termos da função de impressão,
offset_b(0.5, add)
fornece a função add modificada, então podemos passar(1,2)
2ª via (a mesma que ShadowRanger compartilhou):
se chamarmos
offset_b(0.5)
, o que obtemos é na verdade uma função wrapper. Como usamos wrapper,func = wrapper(func)
o que precisamos fazer é obter a nova função,offset_b(0.5)(add)
então damos(1,2)
a essa função, o que nos dáoffset_b(0.5)(add)(1,2)