una resueltos propias otra lista globales funciones funcion ejercicios ejemplos dentro cerrar python function monkeypatching function-composition

resueltos - ¿Cómo multiplicar funciones en python?



lista de funciones de python (3)

Puede usar su clase de hackeo como decorador, tal como está escrito, aunque es probable que desee elegir un nombre más apropiado para la clase.

Me gusta esto:

class Composable(object): def __init__(self, function): self.function = function def __call__(self, *args, **kwargs): return self.function(*args, **kwargs) def __mul__(self, other): @Composable def composed(*args, **kwargs): return self.function(other(*args, **kwargs)) return composed def __rmul__(self, other): @Composable def composed(*args, **kwargs): return other(self.function(*args, **kwargs)) return composed

Luego puedes decorar tus funciones así:

@Composable def sub3(n): return n - 3 @Composable def square(n): return n * n

Y componerlos así:

(square * sub3)(n)

Básicamente es lo mismo que has logrado usando tu clase de hack, pero usándolo como decorador.

def sub3(n): return n - 3 def square(n): return n * n

Es muy fácil componer funciones en python:

>>> my_list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> [square(sub3(n)) for n in my_list] [9, 4, 1, 0, 1, 4, 9, 16, 25, 36]

Desafortunadamente, cuando se quiere usar la composición como clave , es un poco cojo:

>>> sorted(my_list, key=lambda n: square(sub3(n))) [3, 2, 4, 1, 5, 0, 6, 7, 8, 9]

Esto debería ser sorted(my_list, key=square*sub3) , porque diablos, la función __mul__ no se usa para nada más de todos modos:

>>> square * sub3 TypeError: unsupported operand type(s) for *: ''function'' and ''function''

Bueno, vamos a definirlo entonces!

>>> type(sub3).__mul__ = ''something'' TypeError: can''t set attributes of built-in/extension type ''function''

D''oh!

>>> class CoolerFunction(types.FunctionType): ... pass ... TypeError: Error when calling the metaclass bases type ''function'' is not an acceptable base type

D''oh!

class Hack(object): def __init__(self, function): self.function = function def __call__(self, *args, **kwargs): return self.function(*args, **kwargs) def __mul__(self, other): def hack(*args, **kwargs): return self.function(other(*args, **kwargs)) return Hack(hack)

Hey, ahora estamos llegando a algún lugar ..

>>> square = Hack(square) >>> sub3 = Hack(sub3) >>> [square(sub3(n)) for n in my_list] [9, 4, 1, 0, 1, 4, 9, 16, 25, 36] >>> [(square*sub3)(n) for n in my_list] [9, 4, 1, 0, 1, 4, 9, 16, 25, 36] >>> sorted(my_list, key=square*sub3) [3, 2, 4, 1, 5, 0, 6, 7, 8, 9]

¡Pero no quiero una clase de Hack callable! Las reglas de alcance son totalmente diferentes en formas que no entiendo completamente, y esto es incluso más feo que el "lameda" posiblemente. Quiero monkeypatch las funciones . ¿Cómo puedo hacer eso?


Python no (y probablemente nunca) tendrá soporte para la composición de funciones, ya sea a nivel sintáctico o como una función de biblioteca estándar. Hay varios módulos de terceros (como functional ) que proporcionan una función de orden superior que implementa la composición de la función.


Tal vez algo como esto:

class Composition(object): def __init__(self, *args): self.functions = args def __call__(self, arg): result = arg for f in reversed(self.functions): result = f(result) return result

Y entonces:

sorted(my_list, key=Composition(square, sub3))