Yes. You have the basic idea. Here's my guide to flesh that out a bit more ... Classes for Beginners v2.1 May 2023 A lot of beginners struggle to get their heads around classes, but they are pretty much fundamental to object orientated programming (OOPs). They can be thought of as the programming equal of moulds used in factories as templates (or blueprints) for making lots of things that are identical. Imagine pouring molten iron into a mould to make a simple iron pot. You might produce a set of instructions to be included with the pots that tell an owner how to cook using the pot, how to care for it, etc. The same instructions apply to every pot, but what owners actually do is entirely up to them. Some might make soup, another person a stew, etc. Python classes A class defines the basics of a possible Python object and some methods that come with it Methods are like functions, but apply to objects, known as instances, made using a class When we create a Python object using a class, we call it "creating an instance of a class" - an instance is just another Python object If you have a class called Room, you would create instances like this: lounge = Room() kitchen = Room() hall = Room() As you would typically want to store the main dimensions (height, length, width) of a room, whatever it is used for, it makes sense to define that when the instance is created. You would therefore have a method called __init__ that accepts height, length, width and when you create an instance of Room you would provide that information: lounge = Room(1300, 4000, 2000) The __init__ method is called automatically when you create an instance. It is short for initialise (intialize). It is possible to specify default values in an __init__ method, but this doesn't make a lot of sense for the size of a room. Accessing attributes of a class instance You can reference the information using lounge.height, lounge.width, and so on. These are attributes of the lounge instance. We are assuming the measurements are in mm. A method can be included in the class that converts between mm and ft. Thus, for example, we can then write lounge.height_in_ft(). printing an attribute You can output the value of any attribute by just using the name of the instance followed by a dot and the attribute name. For example, print(lounge.height) property decorator A useful decorator is @property, which allows you to refer to a method as if it is an attribute. This would allow you to say lounge.height_in_ft instead of lounge.height_in_ft(). In the example code shown later, @property is used for width_in_ft but not height_in_ft. The use of self to refer to an instance Methods in classes are usually defined with a first parameter of self: def __init__(self, height, length, width): # code for __init__ def height_in_ft(self): # code to return height The self is a shorthand way of referring to an instance. The automatic passing of the reference to the instance (assigned to self) is a key difference between a function call and a method call. When you use lounge.height_in_ft() the method knows that any reference to self means the lounge instance, so self.height means lounge.height but you don't have to write the code for each individual instance. Thus, kitchen.height_in_ft() and bathroom.height_in_ft() use the same method, but you don't have to pass the height of the instance as the method can reference it using self.height human-readable representation of an instance If you want to output all the information about an instance, that would get laborious. There's a method you can add called __str__ which returns a string representation of an instance. This is used automatically by functions like str and print. The example code below includes both the laborious way and using the above method. magic methods The standard methods you can add that start and end with a double underscore, like __init__, __str__, and many more, are often called magic methods or dunder methods where dunder is short for double underscore. EXAMPLE Room class The code shown at the end of this post/comment will generate the following output: Lounge height: 1300 length: 4000 width: 2000 Snug: height: 1300, length: 2500 width: 2000 Lounge length in feet: 4.27 Snug wall area: 11700000.00 in sq.mm., 125.94 in sq.ft. Snug width in feet: 6.56 Note that a method definition that is preceded by the command, @staticmethod (a decorator) is really just a function that does not include the self reference to the calling instance. It is included in a class definition for convenience and can be called by reference to the class or the instance: Room.mm_to_ft(mm) lounge.mm_to_ft(mm) Here's the code for the full programme: class Room(): def __init__(self, name, height, length, width): self.name = name self.height = height self.length = length self.width = width @staticmethod def mm_to_ft(mm): return mm * 0.0032808399 @staticmethod def sqmm_to_sqft(sqmm): return sqmm * 1.07639e-5 def height_in_ft(self): return Room.mm_to_ft(self.height) @property def width_in_ft(self): return Room.mm_to_ft(self.width) def length_in_ft(self): return Room.mm_to_ft(self.length) def wall_area(self): return self.length * 2 * self.height + self.width * 2 * self.height def __str__(self): return (f"{self.name}: " f"height: {self.height}, " f"length: {self.length} " f"width: {self.width}" ) lounge = Room('Lounge', 1300, 4000, 2000) snug = Room('Snug', 1300, 2500, 2000) print(lounge.name, "height:", lounge.height, "length:", lounge.length, "width:", lounge.width) print(snug) # uses __str__ method # f-strings are used for formatting, the :.2f part formats decimal numbers rounded to 2 places print(f"{lounge.name} length in feet: {lounge.height_in_ft():.2f}") # note, () to call method print(f"{snug.name} wall area: {snug.wall_area():.2f} in sq.mm., " f"{snug.sqmm_to_sqft(snug.wall_area()):.2f} in sq.ft." ) print(f"Snug width in feet: {snug.width_in_ft:.2f}") # note, no () after method