Q-bertsuit Q-bertsuit - 1 month ago 9
Python Question

Difference between methods and functions

I'm doing Code Academy's tutorials on Python, and I'm a bit confused about the definition of method and function. From the tutorial:


You already know about some of the built-in functions we've used on (or to create) strings, such as
.upper()
,
.lower()
,
str()
, and
len()
.


Coming from C++, I would think
.upper()
and
.lower()
would be called methods and
len()
and
str()
functions. In the tutorial, the terms seem to be used interchangeably.

Does Python distinguish between methods and functions in the way C++ does?

Unlike Difference between a method and a function, I'm asking about the particulars of Python. The terms 'method' and 'function' do not seem to always follow the definition given in the accepted answer of the linked question.

Answer

A function is a callable object in Python, i.e. can be called using the call operator (though other objects can emulate a function by implementing __call__). For example:

>>> def a(): pass
>>> a
<function a at 0x107063aa0>
>>> type(a)
<type 'function'>

A method is a special class of function, one that can be bound or unbound.

>>> class A:
...   def a(self): pass
>>> A.a
<unbound method A.a>
>>> type(A.a)
<type 'instancemethod'>

>>> A().a
<bound method A.a of <__main__.A instance at 0x107070d88>>
>>> type(A().a)
<type 'instancemethod'>

Of course, an unbound method cannot be called (at least not directly without passing an instance as argument):

>>> A.a()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method a() must be called with A instance as first argument (got nothing instead)

In Python, in most cases you won't notice the difference between a bound method, a function or a callable object (i.e. an object that implements __call__), or a class constructor. They all look the same, they just have different naming conventions. Under the hood, the objects may look vastly different though.

This means that a bound method can be used as a function, this is one of the many small things that makes Python so powerful

>>> b = A().a
>>> b()

It also means that even though there is a fundamental difference between len(...) and str(...) (the latter is a type constructor), you won't notice the difference until you dig a little deeper:

>>> len
<built-in function len>
>>> str
<type 'str'>