-1

I have a question to ask regarding Python class/object attributes. Look at this piece of code:

class Car:
    def __init__(self, year, model):
        self.__year_model = year
        self.__make = model
        self.__speed = 0 
    def Accelerate(self):
        self.__speed += 5
    def Brake(self):
        self.__speed -= 5
    def get_speed(self):
        print(f"The current speed of this car is {self.__speed} miles")

myCar = Car(2019, 'toyota'.title())
print(f"The name of the car is {myCar.__make} and the manufacturing date is {myCar.__year_model} ")

myCar.Accelerate()
myCar.get_speed()
myCar.Brake()
myCar.get_speed()

When ran from the Python Interpreter, I get an AttributeError like this:

Traceback (most recent call last):
  File "c:\Users\Gin-san\Untitled-2.py", line 14, in <module>
    print(f"The name of the car is {myCar.__make} and the manufacturing date is {myCar.__year_model}")
AttributeError: 'Car' object has no attribute '__make'

Now on that same piece of code, when I change the __year_model and __make attributes by removing the underscores, the code runs:

class Car:
    def __init__(self, year, model):
        self.yearmodel = year
        self.make = model
        self.__speed = 0 
    def Accelerate(self):
        self.__speed += 5
    def Brake(self):
        self.__speed -= 5
    def get_speed(self):
        print(f"The current speed of this car is {self.__speed} miles")

myCar = Car(2019, 'toyota'.title())
print(f"The name of the car is {myCar.make} and the manufacturing date is {myCar.yearmodel}")

myCar.Accelerate()
myCar.get_speed()
myCar.Brake()
myCar.get_speed()
The name of the car is Toyota and the manufacturing date is 2019
The current speed of this car is 5 miles
The current speed of this car is 0 miles

Can I get a reason as to why the code didn't run in the first instance but ran in the second one? Thank you.

noobcoder
  • 11
  • 5

2 Answers2

0

It is because double underscore in python means you are declaring a private variable inside the class. This private variable will not be accessible from outside the defined class

You can get more info here : https://stackoverflow.com/a/1301369/6490675

Nivesh Krishna
  • 158
  • 1
  • 8
0

After reading online and from the Python 3 docs. I found out that the Python Interpreter strips away any variable name with two leading underscores __var by placing the classname _classname__var in front of it. This is to prevent any conflicts when the class is extended later on.

So the first code would rather be:

class Car:
    def __init__(self, year, model):
        self.__year_model = year
        self.__make = model
        self.__speed = 0 
    def Accelerate(self):
        self.__speed += 5
    def Brake(self):
        self.__speed -= 5
    def get_speed(self):
        print(f"The current speed of this car is {self.__speed} miles")

myCar = Car(2019, 'toyota'.title())
print(f"The name of the car is {myCar._Car__make} and the manufacturing date is {myCar._Car__year_model}")

myCar.Accelerate()
myCar.get_speed()
myCar.Brake()
myCar.get_speed()

Note that the __year_model and __make were changed to _Car__year_model and _Car__make when called, in order for them to be accessible.

noobcoder
  • 11
  • 5