Last modified: Dec 06, 2025 By Alexander Williams
Fix TypeError: 'property' object is not callable
Python developers often see this error. It happens when you try to call a property like a function. This guide explains why and how to fix it.
Understanding the Error
The error message is clear. You are treating a property as a callable. In Python, a callable is something you can invoke with parentheses.
Functions and methods are callable. Properties are not. They are special attributes managed by getter and setter methods.
This error is common when using the @property decorator. The decorator turns a method into a property. You access it like an attribute, not a method.
Common Cause: Misusing the Property Decorator
The main cause is incorrect syntax. You define a property but call it with (). Let's look at a wrong example.
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self): # This is a property getter
return 3.14 * self.radius ** 2
# Creating an object
my_circle = Circle(5)
# INCORRECT: Trying to call the property
result = my_circle.area() # This line causes the TypeError
print(result)
Traceback (most recent call last):
File "script.py", line 13, in
result = my_circle.area()
TypeError: 'property' object is not callable
The area is a property. You should access it without parentheses. The correct way is my_circle.area.
The Correct Way to Use Properties
Properties provide an interface for attribute access. They can have getters, setters, and deleters. Here is the correct usage.
class Circle:
def __init__(self, radius):
self._radius = radius # Private attribute
@property
def radius(self):
"""Getter for radius."""
return self._radius
@radius.setter
def radius(self, value):
"""Setter for radius with validation."""
if value <= 0:
raise ValueError("Radius must be positive")
self._radius = value
@property
def area(self):
"""Property to calculate area."""
return 3.14 * self._radius ** 2
# Using the class correctly
my_circle = Circle(5)
print(f"Radius: {my_circle.radius}") # Access property (no parentheses)
print(f"Area: {my_circle.area}") # Access property (no parentheses)
# Using the setter
my_circle.radius = 10 # This calls the setter
print(f"New Area: {my_circle.area}")
Radius: 5
Area: 78.5
New Area: 314.0
Notice no parentheses are used for area or the getter radius. The setter is invoked by assignment.
Another Scenario: Confusing Property with Method
Sometimes you intend a method but accidentally make it a property. If you need to perform an action with parameters, use a method.
class Calculator:
@property
def add(self, a, b): # WRONG: Property cannot take arguments
return a + b
calc = Calculator()
# This will fail because 'add' is a property, not a method.
# calc.add(5, 3)
The fix is to remove the @property decorator if you need arguments.
class Calculator:
def add(self, a, b): # Correct: This is a regular method
return a + b
calc = Calculator()
result = calc.add(5, 3) # This works fine
print(result) # Output: 8
Debugging and Prevention Tips
First, check your class definition. Look for the @property decorator. Remember, properties are accessed like attributes.
Use an IDE with good Python support. It will highlight when you try to call a property. This gives you an early warning.
Read the error traceback carefully. It points to the exact line. Check if the name on that line is a property.
Understand the difference between properties and methods. Properties compute a value from internal state. Methods perform actions.
This error is similar to other common TypeErrors. For instance, you might encounter a Fix TypeError: 'module' object is not callable when incorrectly importing. Or a Fix TypeError: 'method' object is not subscriptable when using square brackets on a method.
Advanced Example: Property with Caching
Properties are great for caching computed values. This is a more advanced use case.
class ExpensiveComputation:
def __init__(self, data):
self.data = data
self._cached_result = None # Cache storage
@property
def result(self):
"""Property that caches an expensive computation."""
if self._cached_result is None:
print("Performing expensive calculation...")
# Simulate a heavy computation
self._cached_result = sum(self.data) * 100
return self._cached_result
obj = ExpensiveComputation([1, 2, 3, 4])
print(obj.result) # Triggers calculation
print(obj.result) # Returns cached value, no calculation
Performing expensive calculation...
1000
1000
The property result is accessed without parentheses. The computation runs only once.
Conclusion
The "property object is not callable" error is a simple syntax issue. You are using parentheses on a property. The fix is to remove them.
Properties are powerful for creating managed attributes. They make your code cleaner and more Pythonic. Always access them like simple attributes.
If you need to pass arguments, use a regular method instead. Understanding this distinction is key to object-oriented Python.
For other common type errors, explore our guides like Fix TypeError: unhashable type 'dict' in Python or Fix TypeError: a bytes-like object is required, not 'str'.
Remember: Properties are for getting, setting, and deleting attributes. Methods are for performing actions. Keep this rule in mind to avoid this error.