method objects vs function objects , Python class instances vs class method objects vs function objects , Python class instances vs class python python

method objects vs function objects , Python class instances vs class


Bound vs Unbound Methods - an explanation.

... or why Python has the behaviour you point out.

So, first off, a note that this is different in 3.x. In 3.x, you will get MyClass.f being a function, and x.f as a method - as expected. This behaviour is essentially a poor design decision that has later been changed.

The reason for this is that Python has the concept of a method that is different to most languages, which is essentially a function with the first argument pre-filled as the instance (self). This pre-filling makes a bound method.

>>> x.foo<bound method MyClass.foo of <__main__.MyClass instance at 0x1004989e0>>

In Python 2.x and before, it was reasoned that a method not attached to an instance would be an unbound method, which was a function with the restriction that the first argument (self), must be an instance of the object. This is then ready to be bound to an instance and become a bound method.

>>> MyClass.foo<unbound method MyClass.foo>

With time, it became clear an unbound method is really just a function with this odd restriction that didn't really matter (that self must be of the 'correct' type), so they were removed from the language (in 3.x). This is essentially duck-typing self, which suits the language.

Python 3.3.0 (default, Dec  4 2012, 00:30:24) >>> x.foo<bound method MyClass.foo of <__main__.MyClass object at 0x100858ed0>>>>> MyClass.foo<function MyClass.foo at 0x10084f9e0>

Further reading.

This is a (condensed, from memory) explanation which can be read in full from Python creator Guido van Rossum's own mouth in his 'History of Python' series.


The tutorial is indeed wrong; both class.functionname and instance.functionname return a method object.

What goes on is that a function is a descriptor and their __get__ method is invoked, returning a method. Methods have a __func__ attribute pointing back to the original function:

>>> class Foo(object):...     def bar(self):...         pass... >>> Foo.bar<unbound method Foo.bar>>>> Foo().bar<bound method Foo.bar of <__main__.Foo object at 0x1090d6f10>>>>> # accessing the original function...>>> Foo.bar.__func__<function bar at 0x1090cc488>>>> # turning a function back into a method...>>> Foo.bar.__func__.__get__(None, Foo)<unbound method Foo.bar>>>> Foo.bar.__func__.__get__(Foo(), Foo)<bound method Foo.bar of <__main__.Foo object at 0x1090d6f90>>

This all has changed in Python 3 though; there Foo.bar returns the function itself, unbound methods no longer exist:

$ python3.3Python 3.3.0 (default, Sep 29 2012, 08:16:08) [GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> class Foo:...     def bar(self):...         pass... >>> Foo.bar<function Foo.bar at 0x105512dd0>>>> Foo.bar.__get__(None, Foo)<function Foo.bar at 0x105512dd0>>>> Foo.bar.__get__(Foo(), Foo)<bound method Foo.bar of <__main__.Foo object at 0x10552fe10>>