João Paulo
João Paulo

Reputation: 6690

Lambda function passing not desired self

Look this code:

class MyClass_1():
    @staticmethod
    def method_1(func):
        return func(1, 2, 3)

class MyClass_2():
    my_func = lambda a,b,c : a*b*c # I need to call this method

    def method_2(self):
        result = MyClass_1.method_1(self.my_func)
        print(result)

My error:

TypeError: () takes 3 positional arguments but 4 were given

I need to call the lambda function my_func in the same way as the code above, but a self is appearing from somewhere I don't know and causing this error.

What am I missing?

Upvotes: 2

Views: 4794

Answers (4)

tdelaney
tdelaney

Reputation: 77377

lambdas are small anonymous functions and can be written in the parameter list of a method directly. Assigning them to a variable is usually not desirable. A typical use of lambda here would be:

class MyClass_1():
    @staticmethod
    def method_1(func):
        return func(1, 2, 3)

class MyClass_2():

    def method_2(self):
        result = MyClass_1.method_1(lambda a,b,c: a*b*c)
        print(result)

MyClass_2().method_2()    

Upvotes: 1

user2555451
user2555451

Reputation:

Since my_func is a class attribute of MyClass_2, you should not be accessing it through self (an instance of the class). Instead, you should be accessing it through the class directly:

result = MyClass_1.method_1(MyClass_2.my_func)
                            ^^^^^^^^^

Demo:

>>> class MyClass_1():
...     @staticmethod
...     def method_1(func):
...         return func(1, 2, 3)
...
>>> class MyClass_2():
...     my_func = lambda a,b,c : a*b*c # I need to call this method
...     def method_2(self):
...         result = MyClass_1.method_1(MyClass_2.my_func)
...         print(result)
...
>>> MyClass_2().method_2()
6
>>>

For more information, you can check out these sources:

Upvotes: 4

BrenBarn
BrenBarn

Reputation: 251488

You need to give your lambda a self argument. Lambdas are just ordinary functions. There is no difference between this:

class Foo():
    my_func = lambda a,b,c : a*b*c

and this

class Foo():
    def my_func(a, b, c):
        return a*b*c

In both cases, my_func is a method, and self will be passed if you call it on an instance.

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1123830

A lambda is just different syntax for defining a function object. Functions in class bodies are always bound and passed a self argument (as they are descriptors).

Simply give your lambda that argument:

my_func = lambda self, a, b, c: a * b * c

The alternative would be for you to unwrap the method and pass in the plain function object:

result = MyClass_1.method_1(self.my_func.__func__)

or to wrap your lambda in a staticmethod object:

my_func = staticmethod(lambda a, b, c: a * b * c)

Upvotes: 3

Related Questions