🔍 What Does "Object is Not Subscriptable" Really Mean in Python?

Manas ShindeManas Shinde
3 min read

If you've ever worked with Python, chances are you've run into this frustrating error:

TypeError: 'NoneType' object is not subscriptable

Or maybe:

TypeError: 'int' object is not subscriptable

So, what does this error mean? Why does it happen? And how can you prevent or fix it?

Let’s demystify the “object is not subscriptable” error — and even learn how to create our own subscriptable objects.


🧠 What Does "Subscriptable" Mean?

In Python, an object is subscriptable if it supports indexing using the square bracket syntax — like obj[index].

Examples of subscriptable objects:

  • Strings ("hello"[1])

  • Lists ([1, 2, 3][0])

  • Tuples ((4, 5, 6)[2])

  • Dictionaries ({"a": 1}["a"])

These objects implement the special method __getitem__(), which makes them subscriptable.

On the flip side, objects like None, int, or float do not support indexing, and using brackets on them will raise a TypeError.


❌ A Common Example of the Error

Here’s a classic example where this error might pop up:

def get_data(connected: bool = True):
    if connected:
        return {"a": 1, "b": 2}
    return None

data = get_data(connected=False)

print(data["a"])  # ❌ TypeError: 'NoneType' object is not subscriptable

What went wrong?

The function get_data() returned None, but we tried to index it like a dictionary. Since None is not subscriptable, Python raised a TypeError.


✅ How to Handle This Properly

Whenever you're working with values that might be None, add a guard condition:

if data is not None:
    print(data["a"])
else:
    print("No data available.")

Or using Python 3.8+’s walrus operator:

if (data := get_data(connected=False)) is not None:
    print(data["a"])

🤓 Other Examples of Non-Subscriptable Objects

Integers are not subscriptable:

num = 100
print(num[0])  # ❌ TypeError: 'int' object is not subscriptable

None is not subscriptable:

value = None
print(value["key"])  # ❌ TypeError

In short: only use indexing with objects that are meant to be indexed — lists, strings, dictionaries, etc.


🧩 Making Your Own Object Subscriptable

Let’s say we want to create a custom class that behaves like a list:

class Integers:
    def __init__(self, numbers: list[int]):
        self.numbers = numbers

    def __getitem__(self, index: int) -> int:
        return self.numbers[index]

Now we can do:

ints = Integers([10, 20, 30, 40, 50])
print(ints[2])  # ✅ Output: 30

Add more power: __setitem__ and __delitem__

class Integers:
    def __init__(self, numbers: list[int]):
        self.numbers = numbers

    def __getitem__(self, index):
        return self.numbers[index]

    def __setitem__(self, index, value):
        self.numbers[index] = value

    def __delitem__(self, index):
        del self.numbers[index]

Now your object supports:

ints[1] = 100
del ints[3]

🛠 Summary

  • Subscriptable objects are those that support indexing (obj[index]).

  • Common subscriptables: lists, strings, tuples, dictionaries.

  • You’ll get a TypeError if you try to index an object that isn’t subscriptable (like None, int, etc.).

  • Prevent it by checking for None before indexing.

  • You can make your own objects subscriptable using __getitem__, __setitem__, and __delitem__.


💡 Final Thought

Errors like “object is not subscriptable” can be confusing at first — but once you understand Python’s data model and dunder methods, you unlock a deeper power to write clean, safe, and elegant code.

Happy coding! 🐍✨

0
Subscribe to my newsletter

Read articles from Manas Shinde directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Manas Shinde
Manas Shinde