Difference Between Functions and Methods in Python

The difference between functions and methods in Python is ownership. A function stands on its own and you call it by name, while a method is a function defined inside a class that you call on an object, which Python passes in automatically as self:

len("Austin")          # function
"Austin".upper()      # method of the str object

My test machine for this one: Python 3.12.5 on Windows 11 Command Prompt, outputs unedited.

In this tutorial, we’ll check what type() says, compare the three method kinds and end with an interview answer.

What are functions and methods in Python?

A function’s built with def outside any class and sees only what you pass in (new to def? See how to define a function in Python). A method is a def inside a class body that you call with dot notation:

def sales_tax(amount, rate=0.0825):
    return round(amount * rate, 2)

class Cart:
    def __init__(self, owner):
        self.owner = owner
        self.items = []

    def add(self, name, price):
        self.items.append((name, price))

cart = Cart("Megan Bowen")
cart.add("Desk lamp", 34.99)          # method
print(f"${sales_tax(34.99):.2f}")     # function

print(type(sales_tax))
print(type(cart.add))
print(type(len), type([].append))

Output:

$2.89
<class 'function'>
<class 'method'>
<class 'builtin_function_or_method'> <class 'builtin_function_or_method'>
Command Prompt output comparing the type of a Python function, a bound method and built-in callables
The plain function reports function and the cart’s add reports method.

C built-ins like [].append report builtin_function_or_method. __init__ is a method too; the __init__ method in Python explains it.

Function object vs bound method: what changes?

Python 3 has no unbound methods. On the class you get the plain function; on an instance Python wraps it in a bound method that remembers the object:

class Invoice:
    def __init__(self, customer, amount):
        self.customer = customer
        self.amount = amount

    def total(self, tax_rate=0.06):
        return round(self.amount * (1 + tax_rate), 2)

inv = Invoice("Alex Wilber", 250.00)

print(Invoice.total)
print(inv.total)
print(inv.total.__self__ is inv)
print(inv.total.__func__ is Invoice.total)
print(f"${inv.total():.2f}", f"${Invoice.total(inv):.2f}")

Output:

<function Invoice.total at 0x000001BA2F369BC0>
<bound method Invoice.total of <__main__.Invoice object at 0x000001BA2F379370>>
True
True
$265.00 $265.00
Command Prompt output showing Invoice.total as a function and inv.total as a bound method in Python
Invoice.total is a function, inv.total is a bound method, and both calls return $265.00.

So inv.total() is shorthand for Invoice.total(inv), and both pass the Python callable() function test.

Instance, class and static methods compared

A class method gets the class as cls, and a static method gets nothing extra:

class Subscription:
    monthly_fee = 12.50

    def __init__(self, user):
        self.user = user

    def bill(self, months):                 # instance method
        return f"{self.user}: ${self.monthly_fee * months:.2f}"

    @classmethod
    def change_fee(cls, new_fee):           # class method
        cls.monthly_fee = new_fee

    @staticmethod
    def is_valid_months(months):            # static method
        return 1 <= months <= 36

sub = Subscription("Adele Vance")
print(sub.bill(3))
Subscription.change_fee(14.99)
print(sub.bill(3))
print(Subscription.is_valid_months(48))

print(type(sub.bill).__name__, type(sub.change_fee).__name__, type(sub.is_valid_months).__name__)

Output:

Adele Vance: $37.50
Adele Vance: $44.97
False
method method function
Command Prompt output of a Python class with an instance method, a class method and a static method
The class method raised the fee for every subscription; the static method acts like a plain function.

I use a static method only for a helper that never touches class data. See class method vs static method in Python and the Python classmethod() function.

Built-in functions vs methods: len(x) vs list.append()

Built-in functions like len() work on many types. Methods like append() belong to one type and often change it in place:

prices = [19.99, 5.49, 3.75]

print(len(prices), prices.__len__())
print(sorted(prices), prices)          # new list
print(prices.sort(), prices)           # in place

print(prices.append(8.25), prices)

Output:

3 3
[3.75, 5.49, 19.99] [19.99, 5.49, 3.75]
None [3.75, 5.49, 19.99]
None [3.75, 5.49, 19.99, 8.25]
Command Prompt output comparing Python built-in functions len() and sorted() with list methods sort() and append()
sorted() returns a new list; sort() and append() change it and return None.

Under the hood, len(x) calls x.__len__(). See the len() function in Python and the full list of built-in functions in Python.

Functions vs methods: key differences table

FeatureFunctionMethod
DefinedWith def outside a classWith def inside a class
Called asname(args)obj.name(args)
First argumentNone addedself (or cls)
type() outputfunctionmethod when bound

Properties blur the line since they look like attributes but run code; here’s Python property vs methods.

Common errors when calling methods

You’ll hit these two TypeError messages sooner or later:

class Order:
    def ship():                      # forgot self
        pass

    def total(self):
        pass

for call in (lambda: Order().ship(),
             lambda: Order.total()):
    try:
        call()
    except TypeError as err:
        print("TypeError:", err)

Output:

TypeError: Order.ship() takes 0 positional arguments but 1 was given
TypeError: Order.total() missing 1 required positional argument: 'self'

Forget self and the object is one argument too many; call through the class and self is missing. A second def with the same name replaces the first, as constructor overloading in Python shows.

How do you answer “function vs method” in an interview?

Say this: a method is a function defined in a class and called on an object (passed as self). Every method is a function, but not every function is a method.

More Python callables worth a look:

Frequently asked questions

What is the main difference between a function and a method in Python?

A function is called by name. A method lives in a class and is called on an object, which it receives as self.

Is every method a function in Python?

Yes. It’s a function stored on a class; through an instance, Python wraps it in a bound method.

Is len() a function or a method?

It’s a built-in function that calls the object’s __len__() method for you.

Does Python 3 have unbound methods?

No. ClassName.method returns a plain function, so you pass the instance yourself.

Is a static method a function or a method?

It lives in a class but gets no self or cls, so it acts like a plain function.

Where does the Python documentation explain method objects?

See method objects in the official Python tutorial.