Syntax
class ClassName:
def __init__(self, parameters):
# initialization
def method(self):
# method bodyExamples
Basic Class Definition
Creating a simple class with attributes and methods.
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} says Woof!")
def info(self):
print(f"{self.name} is {self.age} years old")
# Create instances
dog1 = Dog("Buddy", 3)
dog2 = Dog("Max", 5)
# Use methods
dog1.bark() # Buddy says Woof!
dog2.info() # Max is 5 years oldClass with Properties
Using properties and encapsulation to control attribute access.
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.__balance = balance # Private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
print(f"Deposited ${amount}. New balance: ${self.__balance}")
else:
print("Invalid amount")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
print(f"Withdrew ${amount}. New balance: ${self.__balance}")
else:
print("Insufficient funds or invalid amount")
def get_balance(self):
return self.__balance
account = BankAccount("Alice", 1000)
account.deposit(500)
account.withdraw(200)
print(f"Current balance: ${account.get_balance()}")Inheritance
Creating child classes that inherit from parent classes.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound")
class Cat(Animal):
def speak(self):
print(f"{self.name} says Meow!")
class Bird(Animal):
def __init__(self, name, can_fly=True):
super().__init__(name)
self.can_fly = can_fly
def speak(self):
print(f"{self.name} says Tweet!")
def fly(self):
if self.can_fly:
print(f"{self.name} is flying!")
else:
print(f"{self.name} cannot fly")
cat = Cat("Whiskers")
bird = Bird("Tweety")
penguin = Bird("Pingu", can_fly=False)
cat.speak()
bird.speak()
bird.fly()
penguin.fly()Class Methods and Static Methods
Understanding different types of methods in classes.
class MathOperations:
pi = 3.14159 # Class attribute
def __init__(self, value):
self.value = value # Instance attribute
# Instance method
def square(self):
return self.value ** 2
# Class method
@classmethod
def circle_area(cls, radius):
return cls.pi * radius ** 2
# Static method
@staticmethod
def add(a, b):
return a + b
# Instance method usage
math = MathOperations(5)
print(f"Square: {math.square()}")
# Class method usage (no instance needed)
area = MathOperations.circle_area(10)
print(f"Circle area: {area}")
# Static method usage
sum_result = MathOperations.add(3, 7)
print(f"Sum: {sum_result}")Special Methods (Magic Methods)
Implementing special methods to customize class behavior.
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
# String representation
def __str__(self):
return f"{self.title} by {self.author}"
# Detailed representation
def __repr__(self):
return f"Book('{self.title}', '{self.author}', {self.pages})"
# Length
def __len__(self):
return self.pages
# Comparison
def __lt__(self, other):
return self.pages < other.pages
# Addition
def __add__(self, other):
return self.pages + other.pages
book1 = Book("Python Basics", "John Doe", 300)
book2 = Book("Advanced Python", "Jane Smith", 450)
print(str(book1)) # Python Basics by John Doe
print(repr(book1)) # Book('Python Basics', 'John Doe', 300)
print(len(book1)) # 300
print(book1 < book2) # True
print(book1 + book2) # 750Real-World Example
A practical class implementation for managing a shopping cart.
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
class ShoppingCart:
def __init__(self):
self.items = []
def add_item(self, product, quantity=1):
self.items.append({
'product': product,
'quantity': quantity
})
print(f"Added {quantity}x {product.name}")
def remove_item(self, product_name):
self.items = [item for item in self.items
if item['product'].name != product_name]
print(f"Removed {product_name}")
def get_total(self):
total = sum(item['product'].price * item['quantity']
for item in self.items)
return total
def display_cart(self):
if not self.items:
print("Cart is empty")
return
print("\n=== Shopping Cart ===")
for item in self.items:
p = item['product']
q = item['quantity']
subtotal = p.price * q
print(f"{p.name} x{q} - ${subtotal:.2f}")
print(f"Total: ${self.get_total():.2f}\n")
# Usage
cart = ShoppingCart()
laptop = Product("Laptop", 999.99)
mouse = Product("Mouse", 29.99)
cart.add_item(laptop, 1)
cart.add_item(mouse, 2)
cart.display_cart()
cart.remove_item("Mouse")
cart.display_cart()Best practices
- Use PascalCase for class names (MyClass, not my_class or myclass)
- Always define __init__ method to initialize instance attributes
- Use self as the first parameter name in instance methods (convention)
- Implement __str__ and __repr__ methods for better debugging and printing
- Use properties (@property) for computed attributes and validation
- Keep classes focused on a single responsibility - don't make "god objects"
- Document your classes with docstrings explaining their purpose and usage
- Use private attributes (prefix with __) when you want to prevent direct access
At a glance
- Purpose
- Scripting and general-purpose applications
- File extension
- .py
- Runs in
- Python interpreter
- Usually used with
- Python standard library and packages
Specifications & further reading
Related Python documentation
Inheritance lets a class (the child or subclass) reuse and extend the attributes and methods of another class (the parent or superclass), written as class Child(Parent). The built-in super() function gives access to the parent class's methods from within the child, most commonly used to call the parent's __init__ so the child doesn't have to duplicate its setup logic. Python also supports multiple inheritance, where a class inherits from more than one parent.Magic (Dunder) Methods
Magic methods, also called dunder (double underscore) methods, let your custom classes hook into Python's built-in syntax and behavior. __init__ runs on object creation, __str__ controls how an object is displayed with print(), __eq__ and __lt__ control comparisons, __len__ controls the len() function, and __add__ lets objects respond to the + operator. Implementing these makes your custom classes feel like natural, first-class Python types.@property
The @property decorator lets you define a method that can be accessed like a plain attribute, without parentheses. This is useful for computed values that should look like simple attributes, and for adding validation logic that runs whenever an attribute is set, via a matching @x.setter. Properties let you start with simple public attributes and later add logic without breaking any code that uses the class.@staticmethod and @classmethod
Regular instance methods automatically receive self, the specific object they were called on. @staticmethod methods receive neither self nor the class - they behave like a plain function that just happens to live inside a class, grouped there for organizational purposes. @classmethod methods receive the class itself (conventionally named cls) instead of an instance, making them useful for alternative constructors that build an instance in a different way.