# Nakafa Framework: LLM

URL: /en/subject/university/bachelor/ai-ds/ai-programming/everything-object-python
Source: https://raw.githubusercontent.com/nakafaai/nakafa.com/refs/heads/main/packages/contents/subject/university/bachelor/ai-ds/ai-programming/everything-object-python/en.mdx

Output docs content for large language models.

---

export const metadata = {
    title: "Everything is an Object in Python",
    description: "Discover Python's object-oriented nature with hands-on examples. Explore how numbers, strings, lists, functions become objects with methods and attributes.",
    authors: [{ name: "Nabil Akbarazzima Fatih" }],
    date: "07/26/2025",
    subject: "AI Programming",
};

## Basic Object-Oriented Programming Concepts

Python is a programming language that adopts the object-oriented programming or OOP paradigm. One of Python's fundamental principles is that everything is an object. This concept might sound abstract at first, but it's actually very natural and similar to how we view the real world.

Imagine the world around us. All objects have characteristics and can do something. A car has color, brand, and speed, and can move, stop, and honk its horn. Similarly in Python, every data and function is an object that has attributes and can perform certain actions.

## Programming Paradigm Comparison

### Procedural Languages

In procedural programming languages, state and actions are separated. Data and functions that operate on that data are separate from each other.

<CodeBlock 
  data={[{
    language: "c",
    filename: "procedural_parking.c",
    code: `// 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;
}`
  }]}
/>

In the procedural approach, you can see that data (struct) and functions are separate. Functions accept data as parameters and modify them from outside.

### Object-Oriented Languages

In object-oriented programming languages, state and actions are combined into one unit called a class. Attributes describe state, while methods describe actions that can be performed on that state.

<CodeBlock 
  data={[{
    language: "python",
    filename: "oop_parking.py",
    code: `# 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}")`
  }]}
/>

In the object-oriented approach, data and functions that operate on that data are packaged in one unit. Objects have the responsibility to manage their own state.

## Parking System as an Analogy

Let's use a parking system as an example to understand the concept of objects. In the real world, a parking system has characteristics like maximum capacity and number of occupied spaces. This system can also perform actions like accepting cars entering or leaving.

<CodeBlock 
  data={[{
    language: "python",
    filename: "parking_system_detailed.py",
    code: `class ParkingSystem:
    def __init__(self, capacity):
        """Initialize parking system with certain capacity"""
        self.capacity = capacity
        self.occupied = 0
        self.vehicles = []  # List of parked vehicles
    
    def park_vehicle(self, vehicle_plate):
        """Method to park a vehicle"""
        if self.occupied >= self.capacity:
            return f"Parking full! Cannot park {vehicle_plate}"
        
        self.vehicles.append(vehicle_plate)
        self.occupied += 1
        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)
            self.occupied -= 1
            return f"Vehicle {vehicle_plate} exited parking"
        else:
            return f"Vehicle {vehicle_plate} not found"
    
    def get_status(self):
        """Method to view parking status"""
        available = self.capacity - self.occupied
        return {
            'capacity': self.capacity,
            'occupied': self.occupied,
            'available': available,
            'vehicles': self.vehicles
        }
    
    def is_full(self):
        """Method to check if parking is full"""
        return self.occupied >= 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())`
  }]}
/>

## Object Concepts in Data Types

In Python, the concept of "everything is an object" means every data you create has attributes and methods. Let's explore this concept deeper.

### Numbers are Objects

<CodeBlock 
  data={[{
    language: "python",
    filename: "numbers_as_objects.py",
    code: `# 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 are Objects

<CodeBlock 
  data={[{
    language: "python",
    filename: "strings_as_objects.py",
    code: `# Strings in Python are very powerful objects
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 are Objects

<CodeBlock 
  data={[{
    language: "python",
    filename: "lists_as_objects.py",
    code: `# 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 are Objects

<CodeBlock 
  data={[{
    language: "python",
    filename: "dicts_as_objects.py",
    code: `# 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

One interesting thing about Python is that functions are also objects. This allows you to treat functions like regular data.

<CodeBlock 
  data={[{
    language: "python",
    filename: "functions_as_objects.py",
    code: `# 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
    else:
        return indonesian_greet

# 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))                    # 25`
  }]}
/>

## Classes and Instances as Objects

A class is a blueprint for creating objects, while an instance is an object created from that class.

<CodeBlock 
  data={[{
    language: "python",
    filename: "class_and_instances.py",
    code: `# 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 Indonesia`
  }]}
/>

## Special Methods

Python has special methods that start and end with double underscores. These methods allow your objects to behave like built-in types.

<CodeBlock 
  data={[{
    language: "python",
    filename: "magic_methods.py",
    code: `class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance
    
    def __str__(self):
        """Readable string representation"""
        return f"BankAccount({self.owner}, USD{self.balance:,})"
    
    def __repr__(self):
        """String representation for debugging"""
        return f"BankAccount('{self.owner}', {self.balance})"
    
    def __len__(self):
        """Return length of owner name"""
        return len(self.owner)
    
    def __eq__(self, other):
        """Compare two bank accounts"""
        if isinstance(other, BankAccount):
            return self.balance == other.balance
        return False
    
    def __lt__(self, other):
        """Less than comparison"""
        if isinstance(other, BankAccount):
            return self.balance < other.balance
        return False
    
    def __add__(self, amount):
        """Add balance (deposit)"""
        if isinstance(amount, (int, float)) and amount > 0:
            self.balance += amount
        return self
    
    def __sub__(self, amount):
        """Subtract balance (withdraw)"""
        if isinstance(amount, (int, float)) and amount > 0:
            if amount <= self.balance:
                self.balance -= amount
            else:
                print("Insufficient balance!")
        return self
    
    def __bool__(self):
        """True if has balance, False if balance is 0"""
        return self.balance > 0

# Creating objects
account1 = BankAccount("Alice", 1000000)
account2 = BankAccount("Bob", 500000)

# Magic methods in action
print(account1)                     # __str__
print(repr(account1))               # __repr__
print(len(account1))                # __len__ (name length)

# Comparison
print(account1 == account2)         # __eq__
print(account1 > account2)          # __lt__ (reversed)

# Arithmetic operations
account1 + 500000                   # __add__ (deposit)
print(account1)

account1 - 200000                   # __sub__ (withdraw)
print(account1)

# Boolean conversion
empty_account = BankAccount("Charlie", 0)
print(bool(account1))               # True
print(bool(empty_account))          # False

# Using in conditionals
if account1:
    print(f"{account1.owner} has balance")
else:
    print(f"{account1.owner} has no balance")`
  }]}
/>

## Object-Oriented Programming Practice

Let's create a more complex example to understand how OOP is applied in real scenarios.

<CodeBlock 
  data={[{
    language: "python",
    filename: "library_management.py",
    code: `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"))`
  }]}
/>

By understanding the concept that everything is an object in Python, you can write code that is more structured, easier to understand, and easier to maintain. Object-oriented programming allows you to model real-world problems into code in a natural and intuitive way.