Python Tutorial
Python is a high-level, interpreted, general-purpose programming language. This tutorial covers everything from basics to advanced internals — with every concept explained, examples to run, and quizzes to test yourself.
What is Python?
Python was created by Guido van Rossum and released in 1991. It emphasises readability and simplicity — Python code reads almost like English.
Why is Python Widely Used?
- Readable syntax – reduces the learning curve dramatically.
- Versatile – web dev (Django/FastAPI), data science (NumPy/Pandas), AI/ML (TensorFlow), scripting, automation.
- Huge ecosystem – PyPI hosts over 450,000 packages.
- Interpreted – no compilation step; great for rapid prototyping.
- Cross-platform – runs on Windows, Linux, macOS.
- Strong community – extensive documentation and support.
Key Features of Python
- Interpreted – executed line by line at runtime.
- Dynamically typed – no need to declare variable types.
- Object-oriented – full OOP support with classes and inheritance.
- Functional programming – lambda, map, filter, reduce.
- Automatic memory management – garbage collection via reference counting.
- "Batteries included" – vast standard library.
- Indentation-based syntax – uses whitespace instead of braces.
import this in your Python shell to read it.Your First Python Program
Every Python journey starts with a simple print statement. Try it in the compiler below:
print("Hello from Skillfort!") name = "Alice" age = 25 print(f"My name is {name} and I'm {age} years old.")
Which of the following best describes Python?
Python Data Types
Every value in Python has a type. Understanding Python's built-in data types is essential for writing correct programs.
Built-in Data Types
| Category | Types | Example |
|---|---|---|
| Numeric | int, float, complex | 42, 3.14, 2+3j |
| Sequence | str, list, tuple, range | "hello", [1,2], (1,2) |
| Set | set, frozenset | {1,2,3} |
| Mapping | dict | {"a":1} |
| Boolean | bool | True, False |
| None | NoneType | None |
# Check the type of any value x = 42 y = 3.14 z = "hello" lst = [1, 2, 3] tup = (1, 2) d = {"name": "Alice"} for val in [x, y, z, lst, tup, d]: print(f{val!r:20} → {type(val).__name__}")
Mutable vs Immutable
One of the most important concepts in Python — understanding which objects can change and which cannot.
What is Mutability?
Mutable objects can be changed after creation. Immutable objects cannot — operations on them create new objects.
- Mutable:
list,dict,set,bytearray - Immutable:
int,float,str,tuple,frozenset,bytes
def fn(lst=[]). The list is shared across all calls! Use def fn(lst=None) and assign inside.# Mutable — changed in place my_list = [1, 2, 3] my_list[0] = 99 print("List after change:", my_list) # Immutable — creates new object my_str = "hello" # my_str[0] = "H" # TypeError! my_str = "Hello" # new object print("String:", my_str) # id() shows memory address a = 10 print("Before:", id(a)) a += 1 print("After:", id(a), "(new object!)")
Which of the following is immutable in Python?
Python Functions
Functions are the building blocks of reusable, organised Python code. Learn about regular functions, lambdas, *args/**kwargs, and recursion.
Defining and Using Functions
A function is a named, reusable block of code defined with def. Functions support type hints (Python 3.5+), default arguments, and docstrings.
def greet(name: str, greeting: str = "Hello") -> str: """Return a personalised greeting.""" return f"{greeting}, {name}!" print(greet("Alice")) print(greet("Bob", greeting="Hi"))
*args and **kwargs
*args collects extra positional arguments into a tuple. **kwargs collects extra keyword arguments into a dict.
def demo(*args, **kwargs): print("args:", args) print("kwargs:", kwargs) demo(1, 2, 3, name="Alice", role="admin") # Lambda: anonymous single-expression function square = lambda x: x ** 2 print("3² =", square(3)) people = [("Alice",30),("Bob",25),("Carol",28)] people.sort(key=lambda p: p[1]) print("Sorted by age:", people)
Generators & Iterators
Generators are one of Python's most powerful features — they produce values lazily, making them ideal for large datasets and infinite sequences.
What is an Iterator?
An iterator implements __iter__() and __next__(). Calling next() on it returns the next value and raises StopIteration when exhausted.
What is a Generator?
A generator is a function that uses yield instead of return. It automatically becomes an iterator — pausing at each yield and resuming on the next next() call.
# Generator function def fibonacci(limit): a, b = 0, 1 while a < limit: yield a # pause here, return a a, b = b, a + b print("Fibonacci under 100:") print(list(fibonacci(100))) # Generator expression (like list comprehension but lazy) gen = (x**2 for x in range(10)) print("Squares:", list(gen)) # Memory comparison import sys lst = [x for x in range(10000)] gen = (x for x in range(10000)) print(f"List size: {sys.getsizeof(lst)} bytes") print(f"Gen size: {sys.getsizeof(gen)} bytes")
What keyword turns a regular function into a generator?
OOP in Python
Object-Oriented Programming in Python — encapsulation, inheritance, polymorphism, and abstraction with real-world examples.
The Four Pillars of OOP
- Encapsulation – bundle data + methods; hide internal state with private attributes (
_name,__name). - Inheritance – child class inherits from parent.
Dog(Animal)inheritsbreathe()and addsbark(). - Polymorphism – same interface, different behaviour.
dog.speak()→ "Woof",cat.speak()→ "Meow". - Abstraction – hide implementation via abstract base classes (
ABC).
from abc import ABC, abstractmethod class Animal(ABC): def __init__(self, name): self.name = name # encapsulation @abstractmethod def speak(self): ... # abstraction def __str__(self): return f"{self.__class__.__name__}({self.name!r})" class Dog(Animal): # inheritance def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" animals = [Dog("Rex"), Cat("Luna"), Dog("Buddy")] for a in animals: print(f"{a} says: {a.speak()}") # polymorphism
Decorators & Closures
Decorators let you extend function behaviour without modifying the function. Closures are the mechanism that makes them work.
What is a Closure?
A closure is an inner function that remembers variables from its enclosing scope even after the outer function has finished.
What is a Decorator?
A decorator is a function that wraps another function to add behaviour. The @decorator syntax is syntactic sugar for fn = decorator(fn).
import time import functools # Closure def make_multiplier(factor): def multiply(x): return x * factor # 'factor' is closed over return multiply double = make_multiplier(2) triple = make_multiplier(3) print("double(5):", double(5)) print("triple(5):", triple(5)) # Decorator def timer(func): @functools.wraps(func) def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) end = time.perf_counter() print(f"{func.__name__} took {(end-start)*1000:.3f}ms") return result return wrapper @timer def sum_to_n(n): return sum(range(n)) result = sum_to_n(1_000_000) print("Sum:", result)
Exception Handling
Python uses try/except blocks to handle errors gracefully. Learn how to catch, raise, log, and create custom exceptions.
try / except / else / finally
try– the block to attempt.except– runs if an exception is raised.else– runs only if NO exception occurred.finally– always runs (cleanup code).
# Custom exception class InsufficientFundsError(Exception): def __init__(self, balance, amount): super().__init__(f"Need {amount}, have {balance}") self.balance = balance self.amount = amount def withdraw(balance, amount): if amount > balance: raise InsufficientFundsError(balance, amount) return balance - amount try: result = withdraw(100, 200) except InsufficientFundsError as e: print("Error:", e) except (TypeError, ValueError) as e: print("Type/Value error:", e) else: print("Withdrawn! Balance:", result) finally: print("Transaction complete.")
Python Coding Labs
14 hands-on challenges. Read the problem, edit the starter code, and run it to verify your solution.
Lab 1 – Palindrome Checker
Write a function that checks whether a given number or string is a palindrome.