Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class variable changed a function into a method, why?

Why does Python turn a free function into an unbound method upon assignment to a class variable?

def make_func(s):
    def func(x):
        return '%s-%d' % (s, x)
    return func

class Foo(object):
    foofunc = make_func('foo')

So this works as expected: (returns "dog-1")

make_func('dog')(1)

But this fails with:

Foo.foofunc(1)

TypeError: unbound method func() must be called with Foo instance as first argument (got int instance instead)

Upon closer inspection, Python turned the "inner" function func inside make_func into a method, but since there's no self, this method will never work. Why does Python do this?

>>> import inspect
>>> inspect.getmembers(Foo, inspect.ismethod)
[('foofunc', <unbound method Foo.func>)]
like image 891
dividebyzero Avatar asked Jul 10 '26 04:07

dividebyzero


1 Answers

Python can't tell "how" you assigned a method to a class attribute. There is no difference between this:

class Foo(object):
    def meth():
        pass

and this

def func():
    pass

class Foo(object):
    meth = func

In both cases, the result is that a function object is assigned to a class attribute named 'meth'. Python can't tell whether you assigned it by defining the function inside the class, or by "manually" assigning it using meth = func. It can only see the "end result", which is an attribute whose value is a function. Either way, once the function is in the class, it is converted to a method via the normal process that notices functions in class definitions and makes them into methods.

like image 93
BrenBarn Avatar answered Jul 11 '26 20:07

BrenBarn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!