Python class variable changed function to method, why?

Why does Python turn a free function into an unbound method when assigning 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 it fails:

Foo.foofunc(1)

      

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

On closer inspection, Python turned the "inner" function func

internally make_func

into a method, but since there isn't self

, this method will never work. Why does Python do this?

>>> import inspect
>>> inspect.getmembers(Foo, inspect.ismethod)
[('foofunc', <unbound method Foo.func>)]

      

+3


source to share


2 answers


Python cannot tell "how" you assigned a method to a class attribute. There is no difference between these:

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

      

and this one



def func():
    pass

class Foo(object):
    meth = func

      

In both cases, the result is that the function object is assigned a class attribute named 'meth'

. Python cannot tell if you assigned it by specifying a function inside a class or by manually assigning it with meth = func

. He can only see the "end result", which is an attribute whose value is a function. In any case, once a function is in a class, it is converted to a method through the normal process, which notices the functions in the class definitions and turns them into methods.

+3


source


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

      

foofunc is a class variable, not a method (for which you need "def"). And you initialize it with make_func (...) so it won't change anymore.



If you want to call Foo.foofunc you need to assign foofunc = make_func

with no parameter.

-2


source







All Articles