Asignar un método para objetar en tiempo de ejecución en Python

Estoy tratando de hacer el equivalente de Javascript en Python:

a.new_func = function(arg1, arg2) { var diff = arg1 - arg2; return diff * diff; } 

En este momento, la forma en que lo hago es definir primero el método y luego asignarlo, pero mi pregunta es si Python permite o no una taquigrafía para hacer la asignación y la parte definitoria en la misma línea. Algo como esto:

 a.new_func = def new_func(arg1, arg2): diff = arg1 - arg2 return diff * diff 

En lugar de esto:

 def new_func(arg1, arg2): diff = arg1 - arg2 return diff * diff a.new_func = new_func 

Me doy cuenta de que la diferencia no es importante, pero todavía estoy interesado en saber si es posible o no.

Python no admite tal syntax.

Supongo que si quisieras, podrías escribir un decorador. Podría verse un poco mejor:

 def method_of(instance): def method_adder(function): setattr(instance, function.__name__, function) return function return method_adder @method_of(a) def new_func(arg1, arg2): stuff() 

O si quieres que el método tenga acceso a ti self :

 def method_of(instance): def method_adder(function): setattr(instance, function.__name__, function.__get__(instance)) return function return method_adder @method_of(a) def new_func(self, arg1, arg2): stuff() 

Lo más cercano a lo que estás buscando son las expresiones lambda, que no son tan fáciles de usar como las funciones escritas correctamente:

 a.new_function = lambda arg1,arg2 : (arg1-arg2)**2 

Sin embargo, en casi todos los casos, definiendo una función y asignándola, la forma en que lo hizo en su ejemplo es la manera de avanzar.

Debes notar que un método de instancia no es un lambda.

Por ejemplo, vamos a hacer un experimento simple en IPython

 In [12]: class A: ....: def f(self): ....: return 1 ....: In [13]: Af__class__ Out[13]: instancemethod In [14]: another_f = lambda self: 1 In [15]: another_f.__class__ Out[15]: function 

Intentar vincular un atributo a un lambda fallará miserablemente al llamarlo.

 In [27]: an_instance = A() In [28]: an_instance.g = lambda self: 2 In [29]: an_instance.g() --------------------------------------------------------------------------- TypeError Traceback (most recent call last)  in () ----> 1 an_instance.g() TypeError: () takes exactly 1 argument (0 given) 

Lo que debes hacer, en cambio, es envolver la lambda con types.MethodType

 In [31]: an_instance.g = types.MethodType(lambda self: 2, an_instance) In [32]: an_instance.g() Out[32]: 2 

Hay algo de magia extraña detrás de los descriptors llamados. En mi opinión, esta no es una solución de OO, pero … Bueno, si desea saber más al respecto, aquí hay un enlace http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html

Así que asumo que quiere saber cómo definir el tiempo de ejecución de la función.

Puede ser algo similar en el enlace crear función dinámicamente