Back to Blog
Python

Python Unbound Method: What It Is and How It Changed

python unbound method: Learn what an unbound method is in Python, how it differs from bound methods, and how Python 3 changed the behavior.

pythonmethod bindingclass methodspython 2 vs 3function objects
Illustration of a Python unbound method being accessed from a class, showing the transition from Python 2 to Python 3.

When you access an instance method through the class itself, Python 2 returns a python unbound method. For example:

class Greeter: def greet(self, name): return f"Hello, {name}" # Access via the class method = Greeter.greet print(type(method)) # In Python 2: <type 'instancemethod'>

The unbound method is a function that expects the instance as its first argument. You can call it by passing an instance explicitly:

g = Greeter() Greeter.greet(g, "Alice") # Works in both Python 2 and 3

In Python 2, Greeter.greet is an unbound method object, distinct from a plain function. This distinction was a source of confusion for many developers.

How Python 3 Changed Unbound Methods

Python 3 removed the unbound method type. Accessing a method via the class now returns a plain function:

class Greeter: def greet(self, name): return f"Hello, {name}" method = Greeter.greet print(type(method)) # <class 'function'>

The behavior of calling the method remains the same: you still need to pass an instance as the first argument. The only difference is the object type. This simplification makes the language more consistent and removes a special case that had little practical benefit.

Bound vs Unbound Methods: Practical Differences

A bound method is created when you access a method through an instance. It automatically captures the instance, so you don't pass self explicitly:

g = Greeter() bound = g.greet print(bound("Bob")) # "Hello, Bob"

An unbound method (or a plain function in Python 3) requires you to pass the instance manually. The practical difference matters when you inspect method types or when you pass methods around as callbacks.

For example, inspect.ismethod returns True for a bound method in both Python 2 and 3, but it returns True for an unbound method only in Python 2. In Python 3, inspect.ismethod(Greeter.greet) is False, while inspect.isfunction is True.

Common Scenarios Where Unbound Methods Appear

You encounter unbound methods when you intentionally access a method via the class rather than an instance. This often happens in metaprogramming, when building decorators, or when you need to call a method without instantiating the class.

Another common scenario is passing a method as a callback. If you pass Greeter.greet to a function that expects a callable, you must provide the instance at call time. This is different from passing g.greet, which already has the instance bound.

Compatibility Considerations for Python 2 and 3

If your codebase supports both Python 2 and Python 3, you need to be aware of the type difference. Code that relies on inspect.ismethod to detect unbound methods will behave differently. For example:

import inspect class A: def method(self): pass if inspect.ismethod(A.method): print("It's a method") else: print("It's a function")

In Python 2, this prints "It's a method"; in Python 3, it prints "It's a function". To write compatible code, you can check for callable or use inspect.isfunction as well. Libraries like six provide helpers to abstract over these differences.

Performance and Runtime Considerations

Creating a bound method object has a small runtime cost because Python allocates a new object each time you access the method through an instance. If you call a method repeatedly in a hot loop, you can avoid this overhead by storing the unbound method (or function) and passing the instance explicitly:

method = Greeter.greet for _ in range(1000): method(g, "Alice")

This avoids creating a bound method object on each iteration. The performance gain is usually minor, but it can matter in tight loops. However, this style is less readable and should be used only when profiling indicates a bottleneck.

Choosing Between Instance Methods, Class Methods, and Static Methods

The concept of unbound methods is closely related to how you define and call methods. Python offers three method types:

Method typeFirst argumentAccess via classTypical use
Instance methodselfReturns a function (or unbound method in Python 2)Operations that require instance state
Class methodclsReturns a bound method to the classOperations that need class-level state
Static methodnoneReturns a plain functionOperations that don't depend on class or instance

Choose an instance method when the logic depends on instance attributes. Use a class method when the logic needs class-level data or when you need a factory. Use a static method when the logic is independent of both. Understanding how these methods appear when accessed via the class helps you predict their behavior in callbacks and higher-order functions.

python unbound method: Practical Usage and Code Examples | RYUSLOG DEV