1

I am trying to add a lambda function to the symbol table of a class:

class B:
    def __init__(self):
        func = lambda self, x: x*x  # <-- Adding 'self' produces error
        self.__dict__['test1'] = func
        print(self.test1(2))
        print(self.test2(2))

    def test2(self, b):
        return b*b*b

b = B()

but this produces an error (running the script with python t.py):

Traceback (most recent call last):
  File "./t.py", line 14, in <module>
    b = B()
  File "./t.py", line 8, in __init__
    print(self.test1(2))
TypeError: <lambda>() missing 1 required positional argument: 'x'

However, if I remove self as an argument to the Lambda function, it works fine.

Why isn't self required as an argument for the Lambda function here?

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • 1
    You may use `self.test1 = types.MethodType(func, self)`, otherwise it will acts like a static method, without Python applying the bit of magic necessary for `self` to refer to the class instance. – Delgan Jun 24 '17 at 18:00
  • @Delgan Thanks, that should work! – Håkon Hægland Jun 24 '17 at 19:48

2 Answers2

1

Class methods' calls:

instance.method(arg1, arg2, ..., argn)

are internally binded to:

instance_class.method(instance, arg1, ..., argn)

where, obviously, instance is self.

You are storing your lambda as an instance attribute, which wouldn't be treated like an instance method. That's why self is not passed automatically as first argument.

Ilario Pierbattista
  • 3,175
  • 2
  • 31
  • 41
  • Thanks for the answer. This makes sense. So adding the lambda function as an instance attribute does not make it an instance method? But how could one make the lambda be treated as an instance method? – Håkon Hægland Jun 24 '17 at 18:12
  • The answer to [this question](https://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object-instance) explains it very well. Try `self.__dict__['test1'] = types.MethodType( func, self )` – Ilario Pierbattista Jun 24 '17 at 18:16
  • Thanks @IlarioPierbattista. I think I found a solution: according to the answer you referred to, I should be able to make it an instance method using: `self.__dict__['test1'] = types.MethodType( func, self )` – Håkon Hægland Jun 24 '17 at 18:25
1

lambda functions are anonymous functions, they are not bound to the class, so in this case you are creating a lambda with 2 arguments (self and x). The error is clearly telling you that when you call the lambda function you are just passing one argument bound to self, so you lack the x.

melpomene
  • 84,125
  • 8
  • 85
  • 148
Netwave
  • 40,134
  • 6
  • 50
  • 93