4

I'm trying to do the Javascript equivalent in Python:

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

Right now, the way I'm doing this is by defining the method first, and then assigning it, but my question is whether or not Python allows a shorthand to do the assigning and the defining part in the same line. Something like this:

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

Instead of this:

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

I realize the difference is not major, but am still interested to know whether or not it's possible.

4 Answers 4

9

Python supports no such syntax.

I suppose if you wanted, you could write a decorator. It might look a bit nicer:

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()

Or if you want the method to have access to 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()
Sign up to request clarification or add additional context in comments.

1 Comment

This actually turned out much neater than I expected. If I ever need to dynamically add methods to objects, I'll probably use a decorator. I wonder how many times this has been reinvented.
6

The closest thing to what you're looking for are lambda expressions, which are not as easy to use as properly written functions:

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

However, in almost all cases, defining a function, and assigning it, the way you have done in your example is the way to go

Comments

1

You should notice that an instance method is not a lambda.

For instance, lets do a simple experiment in 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

Trying to bind an attribute to a lambda will fail miserably when calling it.

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)

What you should do, instead, is wrapping the lambda with types.MethodType

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

In [32]: an_instance.g()
Out[32]: 2

There is some weird magic happening behind called descriptors. In my opinion, this is not a quite OO solution, but... Well, if you want to know more about it, here is a link http://www.cafepy.com/article/python_attributes_and_methods/python_attributes_and_methods.html

Comments

0

So I am assuming you want to know that how to define the function runtime.

May be something similar in the link create function dynamically

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.