- Python is built around object-oriented programming (OOP), which focuses on structuring code using classes and objects.
What is a Class?¶
A class is like a template or blueprint used to create objects.
It defines which attributes (variables) an object will have.
It defines which behaviors (methods) an object can perform.
In Python, we create a class using the
classkeyword.
class ClassName:
# class definition
Example: Defining a Simple Class¶
# Defining a basic class using 'class' keyword
class Drone:
# Attribute
model = "QuadX"
# Display class type
print(type(Drone)) # Output: <class 'type'>
#This code creates a class named `Drone` with one attribute, `model`.
<class 'type'>
What is an Object in Python?¶
An instance of a class that encapsulates data (attributes) and behavior (methods).
In Python, everything is treated as an object—whether it's a string, list, function, or user-defined structure.
Each object carries:
- Attributes → The data associated with the object (also called properties)
- Behaviors → The operations or actions the object can perform (defined as methods)
Characteristics of an Object¶
- Each object in Python has three key properties:
| Property | Description |
|---|---|
| Identity | A unique reference or memory address that distinguishes the object. |
| State | Defined by the attributes (variables) that describe the object’s condition. |
| Behavior | Represented by the methods (functions) that operate on the object’s data. |
- In short: Object = Data (state) + Functions (behavior)
Real-World Analogy: Drone as an Object¶
| Attributes (State) | Behaviors (Methods) |
|---|---|
model_name |
fly() |
battery_level |
record_video() |
altitude |
land() |
A drone object might behave differently depending on its state (e.g., battery low vs full).
So, an object in programming is essentially something that combines data and functionality in one package.
Example:¶
# Define a Drone class with attributes and behaviors
class Drone:
def __init__(self, model_name, battery_level, altitude):
# __init__ is a special method also called a constructor that is automatically called when an object of a class is created.
# It is used to initialize the attributes (variables) of the newly created object. You will learn more in upcoming Tutorial.
self.model_name = model_name
self.battery_level = battery_level
self.altitude = altitude
# Behavior to fly
def fly(self):
print(f"{self.model_name} is flying at {self.altitude} meters altitude.")
# Behavior to record video
def record_video(self):
print(f"{self.model_name} is recording video.")
# Behavior to land
def land(self):
print(f"{self.model_name} is landing now.")
# Create drone object
intensity_drone = Drone("IC-X1", 5000, 500)
# Demonstrating drone behavior
intensity_drone.fly() # Output: IC-X1 is flying at 500 meters altitude.
intensity_drone.record_video() # Output: IC-X1 is recording video.
intensity_drone.land() # Output: IC-X1 is landing now.
IC-X1 is flying at 500 meters altitude. IC-X1 is recording video. IC-X1 is landing now.
Creating an Object (Instance of a Class)¶
- To create an actual object (also called an instance) from a class, you use the class name followed by parentheses (), like calling a function:
Syntax
objectname = classname(arguments)
# Creating an object from the class
drone1 = Drone()
# Accessing the attribute using dot notation
print(drone1.model) # Output: QuadX
QuadX
drone1is now an instance of theDroneclass.- We use
.(dot notation) to access the object's properties and methods.
- When printing out the drone1 object, you will see its name and memory address
print(drone1)
<__main__.Drone object at 0x7b84b25bc230>
- To get an identity of an object, you use the id() which is unique
print(id(drone1))
135809858257456
- The
drone1object is an instance of theDroneclass. The isinstance() function returns True if an object is an instance of a class:
print(isinstance(drone1, Drone)) # True
True
Object Methods¶
- A class can also include methods, which are functions defined within it:
class ChatBot:
def greet(self):
print("Welcome to Intensity Coding!")
bot = ChatBot()
bot.greet() # Output: Welcome to Intensity Coding!
Hello my name is John Welcome to Intensity Coding!
The __init__() Method¶
- This special method automatically runs when an object is created. It’s typically used to initialize attributes.
class Developer:
def __init__(self, name, role):
self.name = name
self.role = role
def show(self):
print(f"{self.name} works as a {self.role}.")
dev = Developer("Riya", "ML Engineer")
dev.show() # Output: Riya works as a ML Engineer.
Riya works as a ML Engineer.
In Python, the process of creating an object involves two distinct steps:
Object Creation: The
__new__()method is responsible for creating a new instance of the class.Object Initialization: Once the object is created, the
__init__()method acts as the constructor to initialize the object’s attributes or perform any setup required.
In simpler terms,
__new__()handles the allocation of the object in memory, while__init__()initializes the object after it has been created.
Understanding self¶
The self keyword represents the instance of the class and is used to access its attributes and methods.
You can technically name it anything, but self is the convention.
class Example:
def __init__(self, x): #Use self as keyword
self.x = x
def display(data):
print("Value:", data.x)
e = Example(99)
e.display() # Output: Value: 99
Value: 99
class Example:
def __init__(ref, x): #Use ref as keyword
ref.x = x
def display(data):
print("Value:", data.x)
e = Example(99)
e.display() # Output: Value: 99
Value: 99
- If we do not use self, Python will not recognize instance variables, leading to an error.
class Example:
def __init__(self, x):
x = x
def display(data):
print("Value:", data.x)
e = Example(99)
e.display()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /tmp/ipython-input-3936307825.py in <cell line: 0>() 7 8 e = Example(99) ----> 9 e.display() /tmp/ipython-input-3936307825.py in display(data) 4 5 def display(data): ----> 6 print("Value:", data.x) 7 8 e = Example(99) AttributeError: 'Example' object has no attribute 'x'
Modifying Object Properties¶
- Every object carries attributes (properties) that hold its data or state.
- After an object has been initialized, we can assign or update these properties by directly accessing them using the dot (
.) operator.
object_name.property_name = value
- This allows us to modify or set the property of an existing object at any time after its creation.
class App:
def __init__(self, name):
self.name = name
app1 = App("ChatAnalyzer")
app1.name = "DataInspector"
print(app1.name) # Output: DataInspector
DataInspector
Deleting Object Properties¶
- We can remove an object’s property using the del keyword. Once a property has been deleted, any attempt to access it will result in an error because it no longer exists.
class Tool:
def __init__(self, name):
self.name = name
tool1 = Tool("AutoML")
del tool1.name # Attribute deleted
# print(tool1.name) # This would raise an AttributeError
Using pass in Empty Classes¶
- If you're drafting a class without content yet, use pass to avoid syntax errors:
class Placeholder:
pass
Built-In Attribute Functions¶
- Python provides built-in functions to interact with attributes dynamically:
| Function | Description |
|---|---|
hasattr(obj, name) |
Checks if an object has a specific attribute |
getattr(obj, name) |
Retrieves an attribute's value |
setattr(obj,name,value) |
Sets an attribute to a specified value. If attribute does not exist, then it would be created. |
delattr(obj, name) |
Deletes an attribute |
class Bot:
def __init__(self):
self.version = 3.2
b1 = Bot()
print(hasattr(b1, 'version')) # True
print(getattr(b1, 'version')) # 3.2
setattr(b1, 'version', 4.0)
delattr(b1, 'version')
True 3.2
Deleting an Object¶
- In Python, we can also delete an entire object using the
delkeyword. Once the object is deleted, it can no longer be accessed, and trying to reference it will raise an error.
Syntax
del object_name
class MLTool:
def __init__(self, name):
self.name = name
tool = MLTool("Classifier")
del tool
# print(tool) # Raises NameError
Empty Objects – Can We Add Properties?¶
- Python’s built-in object() does not allow adding attributes:
obj = object()
# obj.name = "AI" # Raises AttributeError
- Instead, use an empty class if you want to dynamically add attributes:
class DataHolder:
pass
d = DataHolder()
d.name = "NLP Tool"
print(d.name) # Output: NLP Tool
NLP Tool
Python Garbage Collection (Auto Object Deletion)¶
- In Python, you don’t need to manually manage memory like in some other languages (e.g., C or C++). Python has a built-in garbage collector that automatically deletes objects from memory when they are no longer needed.
What is Garbage Collection?¶
Garbage collection is the process of automatically reclaiming memory by destroying objects that are no longer referenced anywhere in your program.
Python tracks how many references exist to every object. When that reference count drops to zero, the memory occupied by the object is released.
Reference Count Example¶
- Let's understand how reference count affects object lifetime:
a = 101 # Creates an integer object <101> and assigns to variable a
b = a # Now <101> has 2 references (a and b)
c = [a] # <101> now has 3 references (a, b, and inside list c)
# Removing references one by one
del a # Reference count drops to 2
b = None # Reference count drops to 1
c[0] = 0 # Now <101> has no references → garbage collector reclaims it
- Once all references to the object are removed, Python's garbage collector automatically deletes it.
Destructor: __del__() Method¶
Sometimes you may want to perform clean-up operations when an object is about to be destroyed—for example, to close a file or release a network connection. Python allows this through a destructor, defined using the special method
__del__().You can define a destructor using
__del__()for cleanup when an object is destroyed:
class Session:
def __init__(self):
print("Session started.")
def __del__(self):
print("Session ended.") # This will run when the object is deleted
# Create a session object
s1 = Session()
# Explicitly delete the object
del s1
Session started. Session ended.
✅ Explanation:
__init__()is the constructor—it runs when the object is created.__del__()is the destructor—it runs when the object is destroyed.del s1 removes the last reference to the object, triggering
__del__().
Built-In Class Attributes¶
- Every class includes special built-in attributes:
| Attribute | Description |
|---|---|
__dict__ |
Class namespace as a dictionary |
__doc__ |
Class documentation string or none, if undefined. |
__name__ |
Class name as a string |
__module__ |
Name of the module where the class is defined |
__bases__ |
Tuple of base classes |
class Engineer:
"""Base class for engineering staff"""
team = "ML Ops"
def __init__(self, name):
self.name = name
print("Engineer.__doc__:", Engineer.__doc__)
print("Engineer.__name__:", Engineer.__name__)
print("Engineer.__module__:", Engineer.__module__)
print("Engineer.__bases__:", Engineer.__bases__)
print("Engineer.__dict__:", Engineer.__dict__)
Engineer.__doc__: Base class for engineering staff
Engineer.__name__: Engineer
Engineer.__module__: __main__
Engineer.__bases__: (<class 'object'>,)
Engineer.__dict__: {'__module__': '__main__', '__doc__': 'Base class for engineering staff', 'team': 'ML Ops', '__init__': <function Engineer.__init__ at 0x7a190b335580>, '__dict__': <attribute '__dict__' of 'Engineer' objects>, '__weakref__': <attribute '__weakref__' of 'Engineer' objects>}
In Python class is also an object¶
- In Python, when you define a class, you usually think of it as a blueprint for creating objects.
- But in python, classes are also objects.
- Almost everything in Python is an object, including Integers, Strings, Functions, Modules, Classes themselves.
- So, when we write:
class Car:
pass
- Behind the scenes, Python actually creates an object named Car.
This object is an instance of a special built-in class called
type.
class Car:
pass
print(type(Car))
# Output: <class 'type'>
<class 'type'>
Key Observation:
Caritself is an object oftype.- That’s why we say “a class is also an object in Python.”
How Python Creates a Class¶
When Python sees a class definition:
- It executes the code inside the class body.
- It collects all attributes and methods into a dictionary.
- It calls type() to create a new class object.
In other words, Python internally does something like:
Car = type("Car", (), {})
# This creates a new class object named Car
- This means the
classkeyword is just a shortcut to create an object usingtype().
Implications¶
- Because a class is an object, you can:
- Pass classes to functions.
- Store them in variables, lists, or dictionaries.
- Dynamically create or modify them at runtime.
def print_class_info(cls):
print(f"Class Name: {cls.__name__}")
print(f"Base Classes: {cls.__bases__}")
print_class_info(Car)
# Output:
# Class Name: Car
# Base Classes: (<class 'object'>,)
Class Name: Car Base Classes: (<class 'object'>,)
Modules vs Classes & Objects in Python¶
Python Modules¶
- A module is a file containing Python definitions (functions, variables, classes) intended to be reused.
- Modules help organize large codebases.
Example: student_module.py¶
# student_module.py
def show_id():
print("Student ID: S12345")
age = 30
Using the module:¶
import student_module
student_module.show_id() # Output: Student ID: S12345
print(student_module.age) # Output: 30
Student ID: S12345 30
Modules vs Dictionaries¶
| Action | Dictionary Syntax | Module Syntax |
|---|---|---|
| Access Value | emp["id"] |
emp.id() |
| Access Variable | emp["age"] |
emp.age |
Classes in Python¶
- A class groups data (attributes) and methods (functions) under one structure.
Example: Defining and Using a Class¶
# student_class.py
class Student:
def __init__(self):
self.age = 30
def show_id(self):
print("Student ID: S12345")
# Creating an object (instantiation)
student_obj = Student()
student_obj.show_id() # Output: Student ID: S12345
print(student_obj.age) # Output: 30
Student ID: S12345 30
Why Prefer Classes Over Modules?¶
Classes are reusable and extensible via inheritance.
Each object created from a class can maintain its own state.
Easier to model real-world behaviors through encapsulation and polymorphism.
OOP Analogy: Dictionary vs Module vs Class¶
# Dictionary
student_dict = {"id": "S12345", "age": 30}
print(student_dict["id"]) # Dictionary style
# Module (after import)
student_module.show_id() # Module style
print(student_module.age)
# Class Instance
student_obj = Student() # Class/Object style
student_obj.show_id()
print(student_obj.age)
S12345 Student ID: S12345 30 Student ID: S12345 30