Skip to main content

OOP: Methods and Variables

Constructor, Instance Methods, and Class vs Instance Variables

· 3 min read

In the previous unit, we introduced classes and objects. Now let's dig deeper into methods, functions that live inside classes, and understand the difference between class variables and instance variables.

OOP: Methods and Variables

The __init__ Method

The __init__ method is a special method called the constructor. Python calls it automatically when you create an object, and it's where you set up the object's initial state.

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

c = Circle(10)

When I create a Circle with Circle(10), Python calls __init__ and passes 10 as the radius argument. The self.radius = radius line stores that value as an attribute on the object.

The self parameter is worth understanding. It's always the first argument to __init__ (and to all instance methods), but you don't pass it explicitly. Python handles it automatically. It's a reference to the object being created or accessed.

Instance Methods

Instance methods are functions defined inside a class that can access the object's attributes through self. Here's the Circle class with an area method:

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

def area(self):
return 3.14 * self.radius ** 2

The area method takes self as its only parameter, giving it access to self.radius. When you call c.area() on a Circle object, Python passes the object as self automatically.

Class Variables vs Instance Variables

Python classes have two kinds of variables, and the distinction matters:

Instance variables are unique to each object. The radius attribute we set in __init__ is an instance variable, so each Circle has its own radius value.

Class variables are shared across all instances of the class. If you change a class variable, the change affects every object.

class Circle:
pi = 3.14 # Class variable

def __init__(self, radius):
self.radius = radius # Instance variable

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

Here, pi is defined at the class level, outside any method. All Circle objects share this single pi value. The radius, defined inside __init__ with self.radius, belongs to each individual circle.

Project: Enhanced Shape Class

Let's extend the Shape class from the previous unit by adding methods for perimeter and area calculations:

import turtle
import math

class Shape:
def __init__(self, t, sides, length):
self.t = t
self.sides = sides
self.length = length

def perimeter(self):
return self.sides * self.length

def area(self):
return (self.sides * self.length ** 2) / (4 * math.tan(math.pi / self.sides))

def draw(self):
for _ in range(self.sides):
self.t.forward(self.length)
self.t.right(360 / self.sides)

screen = turtle.Screen()
screen.setup(width=800, height=600)
screen.bgcolor("white")

t = turtle.Turtle()

hexagon = Shape(t, 6, 50)
hexagon.draw()

t.penup()
t.goto(-150, -150)
t.pendown()
t.write(f"Perimeter: {hexagon.perimeter()}", font=("Arial", 16, "normal"))
t.penup()
t.goto(-150, -175)
t.pendown()
t.write(f"Area: {hexagon.area():.2f}", font=("Arial", 16, "normal"))

t.hideturtle()
turtle.done()

The perimeter method multiplies sides by length. The area method uses a formula for regular polygons that involves the tangent function. Each instance method accesses the object's attributes through self, then performs its calculation.

In the next unit, we'll explore inheritance, creating new classes based on existing ones.