For AI agents: use /llms.txt for the Nakafa content index.
Python supports several ways to organize a program. Procedural code follows a sequence of steps. Functional code transforms data with functions. Object-oriented code groups related data and behavior. One program may combine all three styles.
While a program is running, every Python value is an object. Numbers, functions, classes, and modules each have a type, an identity that distinguishes the object, and a stored value.
An object's type determines the attributes and methods available on it. Since this rule applies to every object, a function can be stored in a list, a class can be passed to another function, and a number can have methods. Python's object model works with procedural, functional, and object-oriented program structures.
In a procedural style, a program is organized around operations and explicit data flow. Data structures and the functions that receive them can remain separate, even in a language that also supports classes.
#include <stdio.h>
// Example of procedural approach in C language
struct ParkSystem {
int max;
int occ;
};
int occupy(struct ParkSystem* ps) {
if (ps->max <= ps->occ) {
return -1;
}
ps->occ++;
return 0;
}
void leave(struct ParkSystem* ps) {
if (ps->occ > 0) {
ps->occ--;
}
}
int main() {
struct ParkSystem ps = {100, 0};
occupy(&ps);
printf("%d %d", ps.max, ps.occ);
return 0;
}Here, the C struct stores parking state and each function receives a pointer to that state. A procedural function can read an input and leave it unchanged.
In an object-oriented style, a class can group related state and behavior behind one interface. Attributes represent object state, while methods define operations that use or update it.
# Example of object-oriented approach in Python
class ParkSystem:
def __init__(self, max_capacity):
self.max = max_capacity
self.occ = 0
def occupy(self):
if self.max <= self.occ:
return -1
self.occ += 1
return 0
def leave(self):
if self.occ > 0:
self.occ -= 1
# Usage
ps = ParkSystem(100)
ps.occupy()
print(f"Max: {ps.max}, Occupied: {ps.occ}")The Python version keeps the parking rules and operations in one class. The occupy method checks the remaining capacity whenever it is called, but outside code can still change the public max and occ attributes directly. This short example therefore does not fully protect the object's state.
In this example, the parking system is an object with state and behavior. Its state records the maximum capacity and the number of occupied spaces. Its methods admit a car or record its departure.
class ParkingSystem:
def __init__(self, capacity):
"""Initialize parking system with certain capacity"""
if capacity <= 0:
raise ValueError("Capacity must be positive")
self.capacity = capacity
self.vehicles = [] # List of parked vehicles
def park_vehicle(self, vehicle_plate):
"""Method to park a vehicle"""
if vehicle_plate in self.vehicles:
return f"Vehicle {vehicle_plate} is already parked"
if len(self.vehicles) >= self.capacity:
return f"Parking full! Cannot park {vehicle_plate}"
self.vehicles.append(vehicle_plate)
return f"Vehicle {vehicle_plate} successfully parked"
def exit_vehicle(self, vehicle_plate):
"""Method to exit parking"""
if vehicle_plate in self.vehicles:
self.vehicles.remove(vehicle_plate)
return f"Vehicle {vehicle_plate} exited parking"
else:
return f"Vehicle {vehicle_plate} not found"
def get_status(self):
"""Method to view parking status"""
occupied = len(self.vehicles)
available = self.capacity - occupied
return {
'capacity': self.capacity,
'occupied': occupied,
'available': available,
'vehicles': tuple(self.vehicles)
}
def is_full(self):
"""Method to check if parking is full"""
return len(self.vehicles) >= self.capacity
# Example usage
parking = ParkingSystem(5)
print(parking.park_vehicle("B 1234 CD"))
print(parking.park_vehicle("B 5678 EF"))
print(parking.get_status())
print(parking.is_full())"Everything is an object" means Python treats runtime values through one object model. Available attributes and methods still depend on each value's type.
# Numbers in Python are objects
number = 42
# Numbers have methods
print(number.bit_length()) # Method to calculate bit length
print(number.__add__(8)) # Method for addition (same as number + 8)
# Float numbers are also objects
price = 15.75
print(price.is_integer()) # Method to check if it's a whole number
print(price.as_integer_ratio()) # Method to convert to ratio
# Even mathematical operation results are objects
result = 10 + 5
print(type(result)) # <class 'int'>
print(dir(result)) # View all available methods# Strings in Python are objects with built-in methods
message = "Learning Python is Fun"
# Strings have many useful methods
print(message.upper()) # LEARNING PYTHON IS FUN
print(message.lower()) # learning python is fun
print(message.title()) # Learning Python Is Fun
print(message.count('n')) # Count letter 'n'
print(message.replace('Python', 'Programming')) # Replace word
# Methods for checking
email = "user@example.com"
print(email.endswith('.com')) # True
print(email.startswith('user')) # True
print(email.find('@')) # Position of '@' character
# Methods for formatting
name = "alice"
age = 25
formatted = "Name: {}, Age: {}".format(name.title(), age)
print(formatted)
# String split and join
words = message.split() # Split into word list
print(words)
rejoined = " ".join(words) # Join back together
print(rejoined)# Lists in Python are dynamic objects
fruits = ["apple", "orange", "mango"]
# Lists have methods for data manipulation
fruits.append("banana") # Add at the end
print(fruits)
fruits.insert(1, "strawberry") # Add at specific position
print(fruits)
fruits.remove("orange") # Remove specific item
print(fruits)
# Methods for searching and sorting
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(numbers.count(1)) # Count occurrences
print(numbers.index(4)) # Find position
numbers.sort() # Sort
print(numbers)
numbers.reverse() # Reverse order
print(numbers)
# List comprehension - pythonic way
squares = [x**2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
# Methods for advanced operations
original = [1, 2, 3]
copy_list = original.copy() # Create copy
original.extend([4, 5]) # Add multiple items
print(f"Original: {original}")
print(f"Copy: {copy_list}")# Dictionaries in Python are flexible objects
student = {
"name": "Alice",
"age": 22,
"major": "Computer Science",
"gpa": 3.8
}
# Dictionaries have methods for manipulation
print(student.get("name")) # Get value safely
print(student.get("height", "Unknown")) # Default value if key doesn't exist
# Methods to view dictionary contents
print(student.keys()) # All keys
print(student.values()) # All values
print(student.items()) # Key-value pairs
# Methods for update and manipulation
student.update({"semester": 6, "age": 23}) # Update multiple values
print(student)
# Pop method to get and remove
gpa = student.pop("gpa")
print(f"Removed GPA: {gpa}")
print(student)
# Dictionary comprehension
grades = {"Math": 85, "Physics": 92, "Chemistry": 78}
passed = {subject: grade for subject, grade in grades.items() if grade >= 80}
print(passed)
# Nested dictionary
university = {
"students": {
"CS": ["Alice", "Bob"],
"Math": ["Charlie", "Diana"]
},
"location": "Jakarta"
}
print(university["students"]["CS"])Functions are also objects in Python. You can pass them as arguments, store them in containers, and assign them to variables like other values.
# Functions in Python are first-class objects
def greet(name):
return f"Hello, {name}!"
def farewell(name):
return f"Goodbye, {name}!"
# Functions have attributes
print(greet.__name__) # Function name
print(type(greet)) # <class 'function'>
# Functions can be stored in variables
my_function = greet
print(my_function("Alice")) # Hello, Alice!
# Functions can be stored in lists
functions = [greet, farewell]
for func in functions:
print(func("Bob"))
# Functions can be used as parameters
def call_function(func, name):
return func(name)
result = call_function(greet, "Charlie")
print(result)
# Functions can be returned from other functions
def get_greeting_function(language):
def english_greet(name):
return f"Hello, {name}!"
def indonesian_greet(name):
return f"Halo, {name}!"
if language == "english":
return english_greet
if language == "indonesian":
return indonesian_greet
raise ValueError(f"Unsupported language: {language}")
# Using returned function
greet_func = get_greeting_function("indonesian")
print(greet_func("Diana")) # Halo, Diana!
# Lambda functions are also objects
square = lambda x: x ** 2
print(type(square)) # <class 'function'>
print(square(5)) # 25A class defines how its instances are constructed and how their shared behavior is resolved. The class itself is also an object, and each instance carries its own instance state.
# Creating class as blueprint
class Student:
# Class attribute (shared by all instances)
university = "University of Indonesia"
def __init__(self, name, major, semester):
# Instance attributes (unique for each instance)
self.name = name
self.major = major
self.semester = semester
self.courses = []
def add_course(self, course):
"""Method to add a course"""
self.courses.append(course)
return f"{self.name} is taking course {course}"
def get_info(self):
"""Method to get student information"""
return {
'name': self.name,
'major': self.major,
'semester': self.semester,
'courses': self.courses,
'university': self.university
}
def __str__(self):
"""Special method for string representation"""
return f"Student({self.name}, {self.major})"
def __len__(self):
"""Special method to get number of courses"""
return len(self.courses)
# Creating instances (objects) from class
student1 = Student("Alice", "Computer Science", 4)
student2 = Student("Bob", "Mathematics", 6)
# Each instance is an object with attributes and methods
print(student1.add_course("Python Programming"))
print(student1.add_course("Data Structures"))
print(student2.add_course("Calculus"))
print(student2.add_course("Linear Algebra"))
# Using methods
print(student1.get_info())
print(student2.get_info())
# Special methods (__str__ and __len__)
print(student1) # Student(Alice, Computer Science)
print(len(student1)) # 2 (number of courses)
# Instances have accessible attributes
print(f"Name: {student1.name}")
print(f"Major: {student1.major}")
print(f"University: {student1.university}")
# Class is also an object
print(type(Student)) # <class 'type'>
print(Student.__name__) # Student
print(Student.university) # University of IndonesiaSpecial methods begin and end with double underscores. Python invokes them through syntax and built-ins such as +, abs(), repr(), and truth testing. Implement one only when its meaning is natural for the domain.
from math import hypot
class Vector2D:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
"""Readable representation for people."""
return f"({self.x}, {self.y})"
def __repr__(self):
"""Unambiguous representation for debugging."""
return f"Vector2D(x={self.x!r}, y={self.y!r})"
def __abs__(self):
"""Return the vector magnitude."""
return hypot(self.x, self.y)
def __eq__(self, other):
"""Compare coordinates when the other value is a Vector2D."""
if not isinstance(other, Vector2D):
return NotImplemented
return self.x == other.x and self.y == other.y
def __add__(self, other):
"""Return a new vector containing the coordinate-wise sum."""
if not isinstance(other, Vector2D):
return NotImplemented
return Vector2D(self.x + other.x, self.y + other.y)
def __bool__(self):
"""Return False for the zero vector and True for every other vector."""
return bool(self.x or self.y)
first = Vector2D(3, 4)
second = Vector2D(1, -2)
print(first) # (3, 4) via __str__
print(repr(first)) # Vector2D(x=3, y=4)
print(abs(first)) # 5.0 via __abs__
print(first == Vector2D(3, 4)) # True via __eq__
combined = first + second # __add__ returns a new vector
print(combined) # (4, 2)
print(first) # (3, 4), unchanged
zero = Vector2D(0, 0)
print(bool(first)) # True
print(bool(zero)) # FalseThe following example combines several classes to model books, members, and library loans.
class Book:
def __init__(self, title, author, isbn):
self.title = title
self.author = author
self.isbn = isbn
self.is_borrowed = False
self.borrower = None
def __str__(self):
status = "Borrowed" if self.is_borrowed else "Available"
return f"{self.title} by {self.author} - {status}"
class Member:
def __init__(self, name, member_id):
self.name = name
self.member_id = member_id
self.borrowed_books = []
def __str__(self):
return f"Member: {self.name} (ID: {self.member_id})"
class Library:
def __init__(self, name):
self.name = name
self.books = []
self.members = []
def add_book(self, book):
"""Add book to library"""
self.books.append(book)
return f"Book '{book.title}' successfully added"
def register_member(self, member):
"""Register new member"""
self.members.append(member)
return f"Member {member.name} successfully registered"
def borrow_book(self, member_id, isbn):
"""Borrow book"""
# Find member
member = None
for m in self.members:
if m.member_id == member_id:
member = m
break
if not member:
return "Member not found"
# Find book
book = None
for b in self.books:
if b.isbn == isbn and not b.is_borrowed:
book = b
break
if not book:
return "Book not available"
# Process borrowing
book.is_borrowed = True
book.borrower = member
member.borrowed_books.append(book)
return f"{member.name} successfully borrowed '{book.title}'"
def return_book(self, member_id, isbn):
"""Return book"""
member = None
for m in self.members:
if m.member_id == member_id:
member = m
break
if not member:
return "Member not found"
book = None
for b in member.borrowed_books:
if b.isbn == isbn:
book = b
break
if not book:
return "Book not found in borrowed list"
# Process return
book.is_borrowed = False
book.borrower = None
member.borrowed_books.remove(book)
return f"{member.name} successfully returned '{book.title}'"
def get_available_books(self):
"""Get list of available books"""
available = [book for book in self.books if not book.is_borrowed]
return available
def get_member_books(self, member_id):
"""Get list of books borrowed by member"""
for member in self.members:
if member.member_id == member_id:
return member.borrowed_books
return []
# Example usage of library system
library = Library("Central Library")
# Adding books
book1 = Book("Python Programming", "John Smith", "978-1234567890")
book2 = Book("Data Science Basics", "Jane Doe", "978-0987654321")
book3 = Book("Machine Learning", "Bob Johnson", "978-1122334455")
print(library.add_book(book1))
print(library.add_book(book2))
print(library.add_book(book3))
# Registering members
member1 = Member("Alice Cooper", "M001")
member2 = Member("Bob Wilson", "M002")
print(library.register_member(member1))
print(library.register_member(member2))
# Borrowing books
print(library.borrow_book("M001", "978-1234567890"))
print(library.borrow_book("M002", "978-0987654321"))
# Viewing book status
print("\nList of all books:")
for book in library.books:
print(book)
print("\nAvailable books:")
for book in library.get_available_books():
print(book)
print(f"\nBooks borrowed by Alice: {len(library.get_member_books('M001'))} books")
# Returning books
print(library.return_book("M001", "978-1234567890"))Python's object model explains why values, functions, and classes can move through the same language mechanisms. Use object-oriented composition when related state and behavior need to be managed together. Use a procedural or functional design when the sequence of steps or the flow of data is easier to explain directly.
Published: . Updated: .