☰

Python Class and Objects

Python Classes and Objects Tutorial: Examples for Beginners

Suppose you run a club with a hundred members. For each person you must store a name, an age and a position. If you keep them in lists, you soon end up asking questions like: was the age at position 1 or position 2 again? One slip, and a member’s age shows up as a job title.

Classes and objects are Python’s answer. A class is the plan, and an object is one real thing built from that plan. You write the plan once, with the name, age and position, and then create as many members as you need. Each one carries its own data, and each one knows how to do its own work, such as printing its details.

This tutorial explains classes and objects from the start. We create a class, build objects, use the __init__ method and the self parameter, add methods, and keep a count of members with a class variable. We also look at the mistakes beginners make most, with the exact error each one gives. Every example here was run, and the output shown is the real output.

What are Classes and Objects in Python?

Python is an object oriented language, which means that it organises code around objects. An object bundles two things: data, called attributes, and actions, called methods. A class is the template that tells Python what attributes and methods an object will have. One class can create any number of objects.

Class and object compared
Point Class Object
What it is The plan or template A real thing made from the plan
Example Member The member called Martin
How many One As many as you want
Created with The class keyword The class name followed by brackets

Think of a club with hundreds of members. Each member has the same kinds of details, but different values. That is exactly the job of a class and its objects.

How to Create a Class in Python

Write the keyword class, the name of the class, and a colon. Then write the body indented by four spaces. The usual style is to start a class name with a capital letter.

python
class ClassName:
    statement_1
    statement_n

If you want an empty class for now, use the keyword pass, which means do nothing. A class body cannot be left blank.

python
class Empty:
    pass

e = Empty()
print(type(e).__name__)
output
Empty

Class Attributes

Values written directly inside the class belong to the class, and every object can see them. Read them with the class name:

python
class Member:
    club = "XYZ club"
    estab = 1992

print(Member.club)
print(Member.estab)
output
XYZ club
1992

A common slip is to write the word class in place of the class name. Python cannot read that, and it stops with an error:

python
print(class.club)
output
SyntaxError: invalid syntax

How to Create an Object in Python

An object is also called an instance of the class. To create one, write the class name with brackets, and store it in a variable. A variable name cannot hold a space, so a line such as object name = Member() gives a SyntaxError. Use a single word, such as test.

python
test = Member()
print(test.club)
print(test.estab)
output
XYZ club
1992

The object test can read the club and estab values that belong to the class.

The __init__() Function

The class attributes above are the same for every object. Real objects need their own values, such as a different name for each member. The __init__ method does this. Python calls it automatically each time you create an object, so it runs once for every new object.

python
class Member:
    def __init__(self, name, age, position):
        self.name = name
        self.age = age
        self.position = position

m = Member("Joe", 28, "officer")
print(m.name)
print(m.age)
print(m.position)
output
Joe
28
officer

When you write Member with three values in brackets, Python makes a new empty object, and calls __init__ with that object as self, and the three values after it. The lines that start with self store the values on the object.

If you give too few values, Python tells you exactly which one is missing:

python
Member("Joe", 28)
output
TypeError: Member.__init__() missing 1 required positional argument: 'position'

Python Object Methods

A method is a function that belongs to a class. Write it inside the class, with self as the first parameter. Keep a space between def and the method name.

python
class Member:
    def __init__(self, name, age, position):
        self.name = name
        self.age = age
        self.position = position

    def testfun(self):
        print("Hello my name is " + self.name)

m1 = Member("Roger", 45, "manager")
m1.testfun()
output
Hello my name is Roger

Notice that we call m1.testfun() with no value in the brackets, although the method has one parameter. Python passes the object itself as self.

The self Parameter

The word self is a reference to the object that is calling the method. It is how a method finds the data of its own object. When Roger calls testfun, self means Roger. When John calls it, self means John.

The name self can be changed. It does not have to be called self, but it must be the first parameter. This works:

python
class Person:
    def __init__(testobj, name, age):
        testobj.name = name
        testobj.age = age

    def funct(xyz):
        print("Hello my name is " + xyz.name)

p = Person("John", 36)
p.funct()
output
Hello my name is John

Do not do this in real code. Every Python programmer expects the word self, and a different name makes your code harder to read. The example only shows that self is a convention, and not a keyword.

Python Class and Object Example: A Club With a Member Count

Now a full example. The class keeps a count of members with a class variable, which is a value shared by the whole class. It goes up by one each time an object is created. The three members are stored in a real list, so one loop can print them all.

python
class Club:
    total_members = 0

    def __init__(self, name, age, position):
        self.name = name
        self.age = age
        self.position = position
        Club.total_members += 1

    def member_info(self):
        print("Name of member:", self.name)
        print("Age of member:", self.age)
        print("Position of member:", self.position)
        print()

members = [Club("Martin", 50, "President"),
           Club("Roger", 35, "Secretary"),
           Club("John", 30, "Treasurer")]

for mem in members:
    mem.member_info()

print(Club.total_members)
output
Name of member: Martin
Age of member: 50
Position of member: President

Name of member: Roger
Age of member: 35
Position of member: Secretary

Name of member: John
Age of member: 30
Position of member: Treasurer

3

The loop at the bottom is one of the biggest wins of using objects. You write the print code once, and it works for every member.

Objects Are Independent

Each object has its own copy of its data. Changing one does not change the others.

python
a = Club("Asha", 29, "Member")
b = Club("Ravi", 31, "Member")
a.age = 30
print(a.age, b.age)
print(a is b, a == b)
output
30 31
False False

Two objects with the same values are still two different objects, so a == b is False here. Python only calls two objects equal when you tell it how, or when they are the same object.

Adding and Deleting Attributes

Python lets you add an attribute to one object after it is created, and delete it later. Use this with care, because other objects of the same class will not have it.

python
a.city = "Kolkata"
print(a.city)
del a.city
print(hasattr(a, "city"))
print(a.city)
output
Kolkata
False
AttributeError: 'Club' object has no attribute 'city'

Class Variables and Instance Variables

A value set inside __init__ with self belongs to that object, and is called an instance variable. A value written in the class body belongs to the class, and is called a class variable. An object can hide a class variable by setting a value of the same name on itself:

python
class Tag:
    label = "shared"

t1 = Tag()
t2 = Tag()
t1.label = "mine"
print(t1.label, t2.label, Tag.label)
output
mine shared shared

The Mutable Class Variable Trap

This is the mistake that surprises beginners most. If a class variable is a list, then every object shares that one list. Put the list inside __init__ so that each object gets its own.

python
class Bad:
    items = []
    def add(self, x):
        self.items.append(x)

class Good:
    def __init__(self):
        self.items = []
    def add(self, x):
        self.items.append(x)

b1, b2 = Bad(), Bad()
b1.add("a")
print(b2.items)

g1, g2 = Good(), Good()
g1.add("a")
print(g2.items)
output
['a']
[]

In the Bad class, we added to b1, but b2 also shows the value, because they share one list.

Printing an Object With __str__

If you print an object with no extra help, Python shows a text with the class name and a memory address, which is not useful. The address changes on every run, so it is not printed here. Define a __str__ method to choose what is shown.

python
class Nice:
    def __init__(self, n):
        self.n = n
    def __str__(self):
        return "Nice object with n = " + str(self.n)

print(Nice(5))
output
Nice object with n = 5

Class Methods and Static Methods

Two extra kinds of methods are useful to know. A class method gets the class, and not the object, as its first parameter. A static method gets neither, and is just a function that sits inside the class for tidiness. Both use a decorator, a line that starts with the at sign.

python
class Counter:
    count = 0
    def __init__(self):
        Counter.count += 1

    @classmethod
    def how_many(cls):
        return cls.count

    @staticmethod
    def is_adult(age):
        return age >= 18

Counter()
Counter()
print(Counter.how_many(), Counter.is_adult(20))
output
2 True

Useful Built In Functions for Objects

Built in functions for objects
Function What it does
type(obj) Tells you which class the object came from
isinstance(obj, Class) Checks if an object belongs to a class, or to a child of it
hasattr(obj, “name”) Checks if an object has an attribute
vars(obj) Shows the attributes of an object as a dictionary
dir(obj) Lists all names that the object can use, including methods
python
print(type(a).__name__, isinstance(a, Club))
print(vars(b))
output
Club True
{'name': 'Ravi', 'age': 31, 'position': 'Member'}

Why Not Just Use a List?

Compare a list and an object for the same member:

python
rec_list = ["Martin", 50, "President"]
rec_obj = Club("Martin", 50, "President")
print(rec_list[2], rec_obj.position)
output
President President

Both give the same answer, but rec_obj.position says what it means, and rec_list[2] makes you remember a number. With a hundred members and many fields, that difference matters. Objects can also carry their own methods, which lists cannot.

Common Class and Object Errors

Class and object errors and fixes
Error Usual cause Fix
IndentationError The class or method body is not indented Indent by four spaces
SyntaxError on class.club Using the word class to read an attribute Use the class name, such as Member.club
SyntaxError on object name A space inside a variable name Use one word or an underscore
TypeError: missing required positional argument Too few values when creating the object Pass every value that __init__ needs
AttributeError: object has no attribute The attribute was never set, or was deleted Set it in __init__
Curly quote SyntaxError Code copied from a web page or a Word file Type straight quotes in your editor

Practice Exercises

  1. Create a Book class with a title, an author and a price. Create three books and print them in a loop.
  2. Add a method that gives a discount of 10 percent and returns the new price.
  3. Add a class variable that counts how many books were created.
  4. Add a __str__ method so that print(book) shows the title and the author.
  5. Create a second class for a Student. Add a list of marks to it, and make sure each student has their own list.

Complete Script to Run Yourself

Here is the full script that was used to test every example on this page. It ran on Python 3.13. A few lines use exec to show errors without stopping the script.

python
import sys

# 1. Empty class and class attributes
class Empty:
    pass

e = Empty()
print(type(e).__name__)

class Member:
    club = "XYZ club"
    estab = 1992

print(Member.club)
print(Member.estab)
test = Member()
print(test.club)
print(test.estab)

# 2. Wrong: class.club
try:
    exec("print(class.club)")
except SyntaxError as e2:
    print("SyntaxError:", e2.msg)

# 3. Wrong: object name = Member()
try:
    exec("object name = Member()")
except SyntaxError as e3:
    print("SyntaxError:", e3.msg)

# 4. __init__
class Member2:
    def __init__(self, name, age, position):
        self.name = name
        self.age = age
        self.position = position

m = Member2("Joe", 28, "officer")
print(m.name)
print(m.age)
print(m.position)

# 5. Missing argument
try:
    Member2("Joe", 28)
except TypeError as e4:
    print("TypeError:", e4)

# 6. Methods
class Member3:
    def __init__(self, name, age, position):
        self.name = name
        self.age = age
        self.position = position

    def testfun(self):
        print("Hello my name is " + self.name)

m1 = Member3("Roger", 45, "manager")
m1.testfun()

# 7. self can have another name
class Person:
    def __init__(testobj, name, age):
        testobj.name = name
        testobj.age = age

    def funct(xyz):
        print("Hello my name is " + xyz.name)

p = Person("John", 36)
p.funct()

# 8. Full example with counter
class Club:
    total_members = 0

    def __init__(self, name, age, position):
        self.name = name
        self.age = age
        self.position = position
        Club.total_members += 1

    def member_info(self):
        print("Name of member:", self.name)
        print("Age of member:", self.age)
        print("Position of member:", self.position)
        print()

members = [Club("Martin", 50, "President"), Club("Roger", 35, "Secretary"), Club("John", 30, "Treasurer")]
for mem in members:
    mem.member_info()
print(Club.total_members)

# 9. Objects are independent
a = Club("Asha", 29, "Member")
b = Club("Ravi", 31, "Member")
a.age = 30
print(a.age, b.age)
print(a is b, a == b)
print(Club.total_members)

# 10. Add and delete attributes
a.city = "Kolkata"
print(a.city)
del a.city
print(hasattr(a, "city"))
try:
    print(a.city)
except AttributeError as e5:
    print("AttributeError:", e5)

# 11. Class vs instance attribute
class Tag:
    label = "shared"

t1 = Tag()
t2 = Tag()
t1.label = "mine"
print(t1.label, t2.label, Tag.label)

# 12. Mutable class attribute trap
class Bad:
    items = []
    def add(self, x):
        self.items.append(x)

class Good:
    def __init__(self):
        self.items = []
    def add(self, x):
        self.items.append(x)

b1, b2 = Bad(), Bad()
b1.add("a")
print(b2.items)
g1, g2 = Good(), Good()
g1.add("a")
print(g2.items)

# 13. Printing an object
class Plain:
    def __init__(self, n):
        self.n = n

class Nice:
    def __init__(self, n):
        self.n = n
    def __str__(self):
        return "Nice object with n = " + str(self.n)

print("<__main__.Plain object at" in str(Plain(1)))
print(Nice(5))

# 14. type, isinstance, vars
print(type(a).__name__, isinstance(a, Club))
print(vars(b))

# 15. classmethod and staticmethod
class Counter:
    count = 0
    def __init__(self):
        Counter.count += 1
    @classmethod
    def how_many(cls):
        return cls.count
    @staticmethod
    def is_adult(age):
        return age >= 18

Counter(); Counter()
print(Counter.how_many(), Counter.is_adult(20))

# 16. List versus class
rec_list = ["Martin", 50, "President"]
rec_obj = Club("Martin", 50, "President")
print(rec_list[2], rec_obj.position)

print(sys.version_info[:2])

Once classes and objects click, the rest of object oriented Python becomes easier. Start by turning one real list of records in your own work, such as customers or products, into a class with a few methods. When that feels natural, move on to inheritance, and then to abstract classes and polymorphism.

Popular Tags:

Python Class and Objects Tutorial