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


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 (likeNone
,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! 🐍✨
Subscribe to my newsletter
Read articles from Manas Shinde directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
