Who passes the additional argument to my `fn` ?

Posted by chunyang on May 21, 2021
TAGS: #python

Recently in an implementation of a functionality, following error keeps showing and drives me crazy.

Traceback (most recent call last):
  File "test_additional_parameter.py", line 13, in <module>
    fn(3)
TypeError: <lambda>() takes 1 positional argument but 2 were given

It is a really weird problem. It is a function which has only one parameter.

Minimal case

from pprint import pprint


class Test:

    fn = lambda x: pprint(x)


a = Test()

fn = a.fn

fn(3)

It is obvious that you may guess fn is a function of an instance and it will receive an argument self from the python interpreter.

methods are functions, they are simply attached to the class, and when that function is called from an instance it gets that instance passed implicitly as the first argument automagically

After changing the method reference using a class, it works as expected.

from pprint import pprint

class Test:
    fn = lambda x: pprint(x)

    @classmethod
    def fn1(cls, x):
        pprint(x)

a = Test.fn
a(3)

b = Test.fn1
b(4)

Methods v.s. Functions, Arguments v.s. Parameters

We have already known the difference of a method and a function. There is also a similar confusing pair: Parameters and Arguments. Parameters are the signature of a method or a function while arguments are passed to the corresponding parameters’ posistion.

Reference