Присвоение метода объекту во время выполнения в 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

Итак, я предполагаю, что вы хотите знать, как определить время выполнения функции.

Может быть что-то похожее в ссылке создать функцию динамически

Другие вопросы по тегам