Souvik Datta
Souvik Datta

Reputation: 106

'float' object is not callable for a Python Program

This python program was designed to find the area and circumference of a circle, but for some reason, I'm getting a TypeError: 'float' object is not callable error when I'm trying to execute the area method.

class Circle:
    pi = 3.14

    def __init__(self, radius=1):
        self.radius = radius
        self.area = radius * radius * self.pi

    def circum(self):
        return self.pi * self.radius * 2


my_circle = Circle(30)
my_circle.area()

Error

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    my_circle.area()
TypeError: 'float' object is not callable

Upvotes: 0

Views: 5685

Answers (3)

eroot163pi
eroot163pi

Reputation: 1815

I want to explain meaning of error. In python there are callable and non callables. Not only functions but also instances of classes can be callable.

float object is not callable (self.area is float). A class is callable if it has __call__ method defined.

1.1()
TypeError: 'float' object is not callable

You will get the same error if you call 1.1() . Because 1.1 is of type float and float does not have __call__ method.

Look at example below

class callable_area(float):
    def __call__(self, x):
        print('My parent is float and can not be called, but i can be')
        print(self * x)
# Product of two numbers
callable_area(1.1)(2.2)

callable_area(1.1) is not a function and is instance of class, but still i can call it like this callable_area(1.1)(2.2).

Now maybe the error you get is just a unconscious mistake and you convert it into function or remove empty brackets infront of it and remove error, but it is also good idea to know what error is implying

Upvotes: 0

Akshay Sehgal
Akshay Sehgal

Reputation: 19312

Explanation:

It's quite straightforward where the issue is. self.area is a variable that is being stored and initialized in the object, not a function. Therefore you can just access it without using () at the end which is used for a function call (or initializing objects of a class, see additional note). Check the code and comments below.

Additional Note: You will see the use of Circle(30) to initialize an object. This convention is used to pass parameters to the __init__ function inside the class while instantiating an object, and it looks the same as if calling a function!

class Circle:
    pi = 3.14

    def __init__(self, radius=1):
        self.radius = radius
        self.area = radius * radius * self.pi

    def circum(self):
        return self.pi * self.radius * 2


my_circle = Circle(30)

#View all the variables initialized in your object
my_circle.__dict__
>>{'radius': 30, 'area': 2826.0}

#Fetch a variable
my_circle.area
>>2826.0

#Call a function
my_circle.circum()
>>188.4

Modification:

Based on what you mention in description this is how you should ideally defined the class you are mentioning -

class Circle:
    def __init__(self, radius=1):
        self.pi = 3.14
        self.radius = radius

    def circum(self):
        self.circum = self.pi * self.radius * 2
        print(self.circum)

    def area(self):
        self.area = self.radius * self.radius * self.pi
        print(self.area) 
        
circle = Circle(30)

#Only radius defined till now
circle.__dict__
#>>{'pi': 3.14, 'radius': 30}


circle.circum()
#>>188.4

circle.area()
#>>2826.0


#After calling the 2 functions, the self dict gets updated with area and circumference
circle.__dict__
#>>{'pi': 3.14, 'radius': 30, 'circum': 188.4, 'area': 2826.0}

Thought process

The way I like to imagine objects of a class is that it is an object is a database with some optional explicit functions defined. The __init__ function initialized the database. You can access everything that the database contains by using the self. Therefore when you pass self to a function, you giving that function access to all of the database that the object is storing. To print everything in that database self you can use my_circle.__self__

Upvotes: 2

Tim Roberts
Tim Roberts

Reputation: 54645

Circle.area is not a method. It is a simple variable. You can read it with my_circle.area.

If you want it to be a function, so you can change the radius and recompute, then you need to make it a function.

    def area(self):
        return self.radius * self.radius * self.pi

Upvotes: 4

Related Questions