Присвоение метода объекту во время выполнения в Python
Я пытаюсь сделать эквивалент Javascript в Python:
a.new_func = function(arg1, arg2) {
var diff = arg1 - arg2;
return diff * diff;
}
Прямо сейчас, способ, которым я делаю это, состоит в том, чтобы сначала определить метод, а затем назначить его, но мой вопрос заключается в том, разрешает ли Python сокращение для выполнения присваивания и определения части в одной строке. Что-то вроде этого:
a.new_func = def new_func(arg1, arg2):
diff = arg1 - arg2
return diff * diff
Вместо этого:
def new_func(arg1, arg2):
diff = arg1 - arg2
return diff * diff
a.new_func = new_func
Я понимаю, что разница не важна, но мне все еще интересно узнать, возможно ли это.
4 ответа
Python не поддерживает такой синтаксис.
Я полагаю, если бы вы хотели, вы могли бы написать декоратор. Это может выглядеть немного лучше:
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()
Или если вы хотите, чтобы метод имел доступ к 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()
Ближе всего к тому, что вы ищете, являются лямбда-выражения, которые не так просты в использовании, как правильно написанные функции:
a.new_function = lambda arg1,arg2 : (arg1-arg2)**2
Однако, почти во всех случаях, определяя функцию и назначая ее, путь, который вы сделали в своем примере, - это путь
Вы должны заметить, что метод экземпляра не является лямбда-выражением.
Например, давайте проведем простой эксперимент в IPython
In [12]: class A:
....: def f(self):
....: return 1
....:
In [13]: A.f.__class__
Out[13]: instancemethod
In [14]: another_f = lambda self: 1
In [15]: another_f.__class__
Out[15]: function
Попытка привязать атрибут к lambda
потерпит неудачу при звонке.
In [27]: an_instance = A()
In [28]: an_instance.g = lambda self: 2
In [29]: an_instance.g()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-29-5122c91d3e8f> in <module>()
----> 1 an_instance.g()
TypeError: <lambda>() takes exactly 1 argument (0 given)
Вместо этого вам следует обернуть лямбду types.MethodType
In [31]: an_instance.g = types.MethodType(lambda self: 2, an_instance)
In [32]: an_instance.g()
Out[32]: 2
За этим происходит какая-то странная магия descriptors
, На мой взгляд, это не совсем оригинальное решение, но... Ну, если вы хотите узнать больше об этом, вот ссылка http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html
Итак, я предполагаю, что вы хотите знать, как определить время выполнения функции.
Может быть что-то похожее в ссылке создать функцию динамически