__getattr__ returning lambda function requiring one argument does not work

Viewed 2070

I am in the process of learning Python 3 and just ran into the getattr function. From what I can tell, it is invoked when the attribute call is not found in the class definition as a function or a variable.

In order to understand the behaviour, I wrote the following test class (based on what I've read):

class Test(object):
    def __init__(self, foo, bar):
        self.foo = foo
        self.bar = bar

    def __getattr__(self, itm):
        if itm is 'test':
            return lambda x: "%s%s" % (x.foo, x.bar)
        raise AttributeError(itm)

And I then initate my object and call the non-existent function test which, expectedly, returns the reference to the function:

t = Test("Foo", "Bar")    
print(t.test)
<function Test.__getattr__.<locals>.<lambda> at 0x01A138E8>

However, if I call the function, the result is not the expected "FooBar", but an error:

print(t.test())
TypeError: <lambda>() missing 1 required positional argument: 'x'

In order to get my expected results, I need to call the function with the same object as the first parameter, like this:

print(t.test(t))
FooBar

I find this behaviour rather strange, as when calling p.some_function(), is said to add p as the first argument.

I would be grateful if someone could shine some light over this headache of mine. I am using PyDev in Eclipse.

5 Answers
Related