2
class Bike:
    def __init__(self, speed):
        self.speed = speed

    def speed(self):
        if (self.speed) > 120:
            print("You are driving fast.")
        else:
            print("You are diving safely.")


bike1 = Bike(32)
bike1.speed()

It is showing:

Traceback (most recent call last):
  File "C:\Users\Syed\PycharmProjects\Muneer Python\Python Beginner Mosh\App.py", line 10, in <module>
    bike1.speed()
TypeError: 'int' object is not callable

I tried using a variable x as self.speed in speed function, but still it is not working. How to fix it?

S.B
  • 13,077
  • 10
  • 22
  • 49
  • 8
    `self.speed=speed` this overwrites the method `speed`. Use different names for the integer variable and the method. – j1-lee Nov 12 '22 at 19:11
  • 1
    just replace `self.speed` with `self.speed_var` or anything other name – YOLO Nov 12 '22 at 19:12
  • 1
    A common convention is to do something like this: *self._speed = speed* Then in your *speed()* function you would write *if self._speed > 120:* Another option would be to make your class function more descriptive - e.g., *def check_speed(self):* That would be especially relevant if you were using @property decorators – DarkKnight Nov 12 '22 at 19:13
  • `speed()` method would be better renamed as `status()` or the like. Most people would expect `speed` to be numeric. In programming in general and OOP in particular, naming matters. – JL Peyret Nov 12 '22 at 20:00

1 Answers1

1

Attributes of an object are stored in its __dict__ namespace(if it has one). This is True for both the class and the instance itself. Your class Bike has a method called speed which is basically a callable attribute(a long with other attributes that is not important for us now). Your instance bike1 has only one instance variable which is its only attribute and is called speed too.

If you check:

print("speed" in Bike.__dict__, Bike.__dict__["speed"])
print("speed" in bike1.__dict__, bike1.__dict__["speed"])

# output:
# True <function Bike.speed at 0x7fe338b8edd0>
# True 32

If we don't take descriptors(and other lookup interception methods) into account, Normally when you request an attribute from an instance by using ., Python checks its namespace first. If it's not there, it checks to see if the attribute is in its class(or type) namespace. If not it proceeds looking class' parents...

In your case, speed is found in the instance's namespace so it is returned. bike1.sleep gives you 32 and you can't call it. You overwrote class's method in instance's namespace.

S.B
  • 13,077
  • 10
  • 22
  • 49