__init__.py, Relative Imports, __main__Learn how to organize code into modules and packages, use __init__.py, perform relative imports, and understand the __main__ entry point.
# mymodule.py
def greet(name):
print(f"Hello, {name}!")
# Using __name__ and __main__
if __name__ == "__main__":
greet("PySank")
# Directory structure for a package:
# mypackage/
# __init__.py
# module1.py
# module2.py
# __init__.py can be empty or set up package exports
# module1.py
def foo():
return "foo"
# module2.py
from .module1 import foo # relative import
# Importing from a package
import mypackage.module1
from mypackage import module2
# Dynamic imports
import importlib
math = importlib.import_module("math")
print(math.sqrt(16))
Explore classes, inheritance, encapsulation, polymorphism, and more in Python's object-oriented programming model.
# Basic class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name} makes a sound."
# Inheritance
class Dog(Animal):
def speak(self):
return f"{self.name} barks."
# Encapsulation
class Counter:
def __init__(self):
self._count = 0 # protected
self.__secret = 42 # private
def increment(self):
self._count += 1
def get_secret(self):
return self.__secret
# Polymorphism
def animal_sound(animal):
print(animal.speak())
animal_sound(Animal("Generic"))
animal_sound(Dog("Buddy"))
# Multiple inheritance
class Flyer:
def fly(self):
return "Flying!"
class Bird(Animal, Flyer):
pass
bird = Bird("Parrot")
print(bird.speak(), bird.fly())
__str__, __repr__, __len__, __call__Special methods ("dunder" = double underscore) let you customize class behavior for built-ins like str(), len(), and more.
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
def __str__(self):
return f"Book: {self.title}"
def __repr__(self):
return f"Book({self.title!r}, {self.pages!r})"
def __len__(self):
return self.pages
def __call__(self, reader):
return f"{reader} is reading {self.title}"
b = Book("Python 101", 350)
print(str(b)) # Book: Python 101
print(repr(b)) # Book('Python 101', 350)
print(len(b)) # 350
print(b("Alice")) # Alice is reading Python 101
# More dunder methods
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # Vector(4, 6)
print(v1 == v2) # False
typing module: List, Dict, Union, Optional)Use type hints to improve code clarity and catch bugs early. The typing module provides advanced types.
from typing import List, Dict, Union, Optional
def add_numbers(a: int, b: int) -> int:
return a + b
def process_items(items: List[str]) -> None:
for item in items:
print(item)
def get_user(id: int) -> Optional[Dict[str, Union[str, int]]]:
if id == 1:
return {"name": "Alice", "age": 30}
return None
# Type hints for variables (Python 3.6+)
name: str = "Bob"
scores: List[int] = [90, 80, 70]
# Type checking with mypy (install separately)
# mypy script.py
with open()Read and write text and binary files safely using with open() context manager.
# Writing text
with open("example.txt", "w", encoding="utf-8") as f:
f.write("Hello, world!\n")
f.write("Another line\n")
# Reading text
with open("example.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())
# Appending
with open("example.txt", "a", encoding="utf-8") as f:
f.write("Appended line\n")
# Binary files
with open("image.png", "rb") as f:
data = f.read(10)
print(data)
# Exception handling
try:
with open("notfound.txt") as f:
f.read()
except FileNotFoundError:
print("File not found!")
Understand Python's exception hierarchy and how to define your own custom exceptions.
# Built-in exception hierarchy
try:
1 / 0
except ZeroDivisionError as e:
print("Caught:", e)
# Custom exception
class MyError(Exception):
pass
def risky():
raise MyError("Something went wrong!")
try:
risky()
except MyError as e:
print("Custom exception:", e)
# Exception chaining
try:
try:
int("abc")
except ValueError as e:
raise RuntimeError("Failed to parse!") from e
except RuntimeError as e:
print("Chained exception:", e)