TypeError: ‘dict’ object is not callable in Python (Fixed)

Updated Oct 23, 2023 ⤳ 6 min read

The “TypeError: ‘dict’ object is not callable” error occurs when you try to call a dictionary (dict object) as if it was a function! Based on some threads on Stack Overflow, the most common cause of this error is using () rather than [] when accessing a dictionary item.

A Python dictionary, often referred to as a “dict,” is a versatile data structure that allows you to store and retrieve data using unique key/value pairs. It’s a fundamental tool for various programming tasks.

Here’s what the error looks like:


Traceback (most recent call last):
  File "/dwd/sandbox/test.py", line 5, in 
    print(book('title'))
          ^^^^^^^^^^^^^
TypeError: 'dict' object is not callable

Calling a Python dict object isn't what you'd do on purpose, though. It usually happens due to a wrong syntax (as mentioned above) or overriding a builtin (or user-defined) function name with a dictionary object.

🎧 Debugging Jam

Calling all coders in need of a rhythm boost! Tune in to our 24/7 Lofi Coding Radio on YouTube, and let's code to the beat – subscribe for the ultimate coding groove!" Let the bug-hunting begin! 🎵💻🚀

Let's explore the common causes and their solutions.

How to fix TypeError: 'dict' object is not callable?

This TypeError happens under various scenarios:

  1. Accessing a dictionary item by () rather than []
  2. Declaring a dictionary with a name that's also the name of a function
  3. Calling a method that's also the name of a property
  4. Calling a method decorated with @property

1. Accessing a dictionary item by () rather than []: The most common cause of this TypeError is accessing a dictionary item by () instead of [].

Based on Python semantics, any identifier followed by a () is a function call. In this case, since () follows a data structure (a dict object), it's like you're trying to call it like it's callable.

As a result, you'll get the "TypeError: ‘dict’ object is not callable" error.


book = {
    'title': 'Head First Python', 'price': 46.01}

 # ⛔ Raises: TypeError: ‘dict’ object is not callable
print(book('title'))

This is how you're supposed to access a dictionary value:


book = {
    'title': 'Head First Python', 'price': 46.01}

print(book['title'])
# Output: Head First Python

print(book.get('price'))
# Output: 46.01

2. Declaring a dictionary with a name that's also the name of a function: A Python function is an object like any other built-in object, such as str, int, float, dict, list, etc.

All built-in functions are defined in the builtins module and assigned a global name for easier access. For instance, dict() builtin function refers to the __builtins__.dict() function.

That said, overriding a function's global name (accidentally or on purpose) with any value (e.g., a dictionary) is technically possible. 

In the following example, we've declared a variable named range containing some config data. In its following line, we use the range() function in a for loop:


# Creating dict object named range
range = {'start': 0, 'end': 200}
# ⚠️ The above line overrides the original value of range (the 'range' class)

 # ⛔ Raises: TypeError: ‘dict’ object is not callable
for item in range(10, 20):
    print(item)

If you run the above code, Python will complain with this type error because we've already assigned the range global variable to our first dictionary.

We have two ways to fix the issue:

  1. Rename the variable range
  2. Explicitly access the range() function from the builtins module (__bultins__.range)

The second approach isn't recommended unless you're developing a module. For instance, if you want to implement an open() function that wraps the built-in open():


# Custom open() function using the built-in open() internally
def open(filename):
     # ...
     __builtins__.open(filename, 'w', opener=opener)
     # ...

In almost every other case, you should always avoid naming your variables as existing functions and methods. But if you've done so, renaming the variable would solve the issue.

So the above example could be fixed like this:


range_config = {'start': 0, 'end': 200}

for item in range(10, 20):
    print(item)

This issue is common with function names you're more likely to use as variable names. Functions such as vars, locals, list, dict, all, or even user-defined functions.

⚠️ Long story short, you should never use a function name (built-in or user-defined) for your variables!

Overriding functions (and calling them later on) is one of the most common causes of the "TypeError: 'dict' object is not callable" error. It's similar to calling integer numbers as if they're callables.

Now, let's get to the less common mistakes that lead to this error.

3. Calling a method that's also the name of a property: When you define a property in a class constructor, it'll shadow any other attribute of the same name.


class Book:
    def __init__(self, title, isbn):
        self.title = title
        self.isbn = isbn

    def isbn(self):
        return self.isbn

isbn = { 'isbn10': '1492051292', 'isbn13': '978-1492051299' }
book = Book('Head First Python', isbn)

print(book.isbn())
# 👆 ⛔ Raises TypeError: 'dict' object is not callable

In the above example, we have a property named isbn - a dictionary to keep ISBN 10 and ISBN 13 of the book. Further down, we defined a method, also named isbn.

However the property isbn shadows the method isbn(). As a result, any reference to isbn returns the property - a dict object - not the method. And if you try to call this dict object, you should expect the "TypeError: ‘dict’ object is not callable" error.

The name get_isbn sounds like a safer and more readable alternative:


class Book:
    def __init__(self, title, isbn):
        self.title = title
        self.isbn = isbn

    def get_isbn(self):
        return self.isbn

isbn = { 'isbn10': '1492051292', 'isbn13': '978-1492051299' }
book = Book('Head First Python', isbn)

print(book.get_isbn())
# Output: {'isbn10': '1492051292', 'isbn13': '978-1492051299'}

4. Calling a method decorated with @property decorator: The @property decorator turns a method into a “getter” for a read-only attribute of the same name. You need to access a getter method without parenthesis, otherwise you'll get a TypeError.


class Book:
    def __init__(self, title, isbn):
        self._title = title
        self._isbn = isbn

    @property
    def isbn(self):
        return self._isbn

isbn = { 'isbn10': '1492051292', 'isbn13': '978-1492051299' }
book = Book('Head First Python', isbn)

print(book.isbn())
# 👆 ⛔ Raises TypeError: 'dict' object is not callable

To fix it, you need to access the getter method without the parentheses:


class Book:
    def __init__(self, title, isbn):
        self._title = title
        self._isbn = isbn

    @property
    def isbn(self):
        return self._isbn

isbn = { 'isbn10': '1492051292', 'isbn13': '978-1492051299' }
book = Book('Head First Python', isbn)

print(book.isbn)
# Output: {'isbn10': '1492051292', 'isbn13': '978-1492051299'}

Problem solved!

Alright, I think it does it! I hope this quick guide helped you fix your problem.

Thanks for reading.

Disclaimer: This post may contain affiliate links. I might receive a commission if a purchase is made. However, it doesn’t change the cost you’ll pay.

`
Exit mobile version