Alex Alex - 2 months ago 12
Python Question

Difference between python lambda functions inside class and def

I have the following code.

class SomeClass:

a = lambda self: self.b()

def __init__(self):
self.b = lambda self: None

s = SomeClass()
s.a()


It give me "TypeError: () takes exactly 1 argument (0 given)". And I want to understand why.
My explanation:


  • a - class method, so
    s.a()
    equlas
    SomeClass.a(s)

  • b - object's attribute (not a method, just a function), that is why
    self.b()
    doesn't equal
    SomeClass.b(self)

    So in
    a = lambda self: self.b()
    argument for
    b
    is missing.
    Am I right?
    P.S. Is it closure effect?

    class SomeClass:

    a = lambda self: self.b()

    def __init__(self):
    self.data = 12
    self.b = lambda: self.data

    s = SomeClass()
    print s.a() #12
    s.data = 24
    print s.a() #24


Answer

Your problem here is the difference between bound methods and functions

Have a simpler example:

class Someclass(object):
    bound = lambda *args: "bound method got {}".format(args)
    def __init__(self):
        self.unbound = lambda *args: "function got {}".format(args)
>>> c = Someclass()

If we look closely, these two functions are not of the same type:

>>> c.bound
<bound method Someclass.<lambda> of <__main__.Someclass object at 0x...>>
>>> c.unbound
<function Someclass.__init__.<locals>.<lambda> at 0x...>

And as a result, when we call them, they receive different arguments:

>>> c.bound(1, 2, 3)
'bound method got (<__main__.Someclass object at 0x...>, 1, 2, 3)'
>>> c.unbound(1, 2, 3)
'unbound got (1, 2, 3)'

Notice that only the "bound" function got a self argument passed in.

Tested in 3.5 - 2.7 might have slightly different names for things

Comments