Introduction to the Python Cheat Sheet
If you’re looking for the most practical Python cheat sheet, you’ve come to the right place. Python is one of the world’s most popular programming languages — loved by beginners for its simplicity and trusted by professionals for its power in web development, data science, artificial intelligence, machine learning, and automation. This Python cheat sheet by Solviyo is your complete reference, covering everything from basic syntax and variables to advanced topics like object-oriented programming, decorators, generators, async, and modules. You can read it online or download the PDF for offline use.
Whether you are a student learning Python for the first time, a developer brushing up for a coding interview, or a data scientist needing a quick reference for daily work, this Python quick reference guide is structured to save you time. It includes ready-to-use examples, copyable code snippets, best practices, and performance notes — all organized into clear sections. Each topic is explained in plain language with practical tips so you can quickly learn Python, revise concepts, or debug faster.
Some of the most searched topics like Python functions, loops, conditionals, data types, string methods, list comprehensions, dictionaries, sets, and classes are covered with examples and tables. Advanced users will find dedicated sections on Python decorators, dataclasses, enums, pattern matching (PEP 634), virtual environments, and dependency management. We also include insights into when to use specific data structures and the subtle differences between class methods, static methods, and instance methods.
For developers preparing for interviews, this page doubles as a Python interview preparation cheat sheet, giving you all the essential Python syntax and tricks in one place. If you prefer offline reading, you can download the Python cheat sheet PDF version for free and keep it handy on your desktop or mobile device. Bookmark this guide now — it’s your ultimate Python quick reference.
Hello Python
Installing
Install Python from the OS package manager or python.org. Example commands:
# Install via apt (Linux)
sudo apt install python3
# macOS (Homebrew)
brew install python
# Windows (winget)
winget install Python.Python.3
# verify with
python3 --version
Running Scripts
Save code as hello.py and run it from the shell:
# hello.py
print("Hello from Solviyo!")
# Run:
python3 hello.py
REPL (Interactive Mode)
Quickly test lines of code in the REPL (use Ctrl+D to exit):
python3
>>> # type expressions and press Enter
>>> 2 + 3
5
>>> print("REPL test - Solviyo")
REPL test - Solviyo
Comments & Documentation
Inline Comments
Use # for single-line comments and short notes. Put explanatory comments where helpful.
# add two numbers
result = 5 + 3
Docstrings
Use triple-quoted strings for function/class/module documentation. Docstrings are accessible via .__doc__ or help().
def greet(name: str) -> str:
"""Return a greeting.
Example:
>>> greet("Solviyo")
'Hello, Solviyo!'
"""
return f"Hello, {name}"
Typing Annotations
Type hints clarify intent and help tooling (linters, autocomplete). They are not enforced at runtime by default.
def add(x: int, y: int) -> int:
"""Add two integers (used in Solviyo examples)."""
return x + y
# Example
result: int = add(2, 3)
Variables & Data Types
Python variables don’t need explicit declaration — they’re created when you assign a value.
# Solviyo example variables
x = 42 # int
pi = 3.14159 # float
name = "Solviyo" # string
is_active = True # boolean
nothing = None # special "no value"
Type Casting
Convert between types using built-in functions:
x = int("5") # string → int
y = float(10) # int → float
z = str(99) # int → string
flag = bool(0) # → False
check = bool(123) # → True
type() to check the data type: type(name).Operators
Arithmetic Operators
a, b = 7, 3
print(a + b) # 10 (addition)
print(a - b) # 4 (subtraction)
print(a * b) # 21 (multiplication)
print(a / b) # 2.333... (division)
print(a // b) # 2 (floor division)
print(a % b) # 1 (modulus)
print(a ** b) # 343 (exponentiation)
Comparison Operators
a, b = 5, 10
print(a == b) # False
print(a != b) # True
print(a > b) # False
print(a < b) # True
print(a >= 5) # True
print(b <= 10) # True
Logical Operators
x, y = True, False
print(x and y) # False
print(x or y) # True
print(not x) # False
Bitwise Operators
Operate on the binary representation of integers.
a, b = 6, 3 # (110, 011 in binary)
print(a & b) # 2 (AND)
print(a | b) # 7 (OR)
print(a ^ b) # 5 (XOR)
print(~a) # -7 (NOT)
print(a << 1) # 12 (left shift)
print(a >> 1) # 3 (right shift)
Membership Operators
text = "Solviyo"
print("S" in text) # True
print("z" not in text) # True
Identity Operators
Check if two variables point to the same object in memory.
x = [1, 2, 3]
y = x
z = [1, 2, 3]
print(x is y) # True (same object)
print(x is z) # False (same value, different object)
print(x is not z) # True
Input & Output
Python provides simple but powerful ways to interact with users and display results.
Printing Output
# Basic printing
print("Hello Solviyo")
# Print multiple values (separated by space by default)
print("Pi =", 3.14159)
# Customize separator and end
print("A", "B", "C", sep="-", end="*")
# Output: A-B-C*
User Input
input() reads a line from standard input and always returns a string.
name = input("Enter your name: ")
print("Welcome,", name)
age = int(input("Enter your age: "))
print("Next year you'll be", age + 1)
Formatted Strings
| Method | Example | Output |
|---|---|---|
| f-string (recommended) | f"Hello {name}" |
Hello Solviyo |
str.format() |
"Pi is {:.2f}".format(3.14159) |
Pi is 3.14 |
| Old style | "%s is %d" % ("Age", 25) |
Age is 25 |
name = "Solviyo"
score = 95
print(f"{name} scored {score}/100")
File Redirection (Shell)
You can redirect program output to a file or read input from a file in the shell:
| Command | Description |
|---|---|
python3 prog.py > out.txt |
Redirect program output to out.txt |
python3 prog.py < in.txt |
Use in.txt as input for the program |
python3 prog.py > out.txt 2>&1 |
Redirect both output and errors to out.txt |
Strings
Slicing
text = "Solviyo"
print(text[0]) # S (first character)
print(text[-1]) # o (last character)
print(text[0:4]) # Solv
print(text[:4]) # Solv
print(text[4:]) # iyo
print(text[::2]) # Slv (every 2nd char)
Common Methods
| Method | Example | Output |
|---|---|---|
.lower() |
"Solviyo".lower() |
solviyo |
.upper() |
"solviyo".upper() |
SOLVIYO |
.strip() |
" hi ".strip() |
hi |
.replace() |
"abc".replace("a","z") |
zbc |
.split() |
"a,b,c".split(",") |
['a','b','c'] |
.join() |
"-".join(["a","b"]) |
a-b |
f-Strings
name = "Solviyo"
score = 99
print(f"{name} scored {score}/100")
pi = 3.14159
print(f"Pi rounded: {pi:.2f}")
Regex Basics
Python’s re module enables pattern matching.
import re
text = "Solviyo has 2 cats and 3 dogs"
nums = re.findall(r"\d+", text) # find all numbers
print(nums) # ['2', '3']
if re.search(r"cats", text):
print("Found 'cats'!")
Lists
Creation & Slicing
items = [1, 2, 3, "Solviyo", True]
print(items[0]) # 1
print(items[-1]) # True
print(items[1:4]) # [2, 3, 'Solviyo']
Common Methods
| Method | Example | Effect |
|---|---|---|
.append() |
nums.append(4) |
Adds element at end |
.extend() |
nums.extend([5,6]) |
Adds multiple elements |
.insert() |
nums.insert(1, 99) |
Insert at index |
.remove() |
nums.remove(99) |
Remove first match |
.pop() |
nums.pop() |
Remove & return last element |
.sort() |
nums.sort() |
Sort in place |
.reverse() |
nums.reverse() |
Reverse in place |
List Comprehensions
# Squares from 0 to 9
squares = [x**2 for x in range(10)]
print(squares)
# Filter even numbers
evens = [x for x in range(10) if x % 2 == 0]
print(evens)
Tuples
Tuples are like lists, but immutable — once created, they cannot be changed. This makes them faster and safe for fixed collections.
Immutability
t = (1, 2, 3)
print(t[0]) # 1
# t[0] = 99 # ❌ Error: 'tuple' object does not support item assignment
Packing & Unpacking
# Packing
point = (10, 20)
# Unpacking
x, y = point
print(x, y) # 10 20
# Extended unpacking
a, *b = (1, 2, 3, 4)
print(a) # 1
print(b) # [2, 3, 4]
Named Tuples
For better readability, use namedtuple (from collections).
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p[0], p[1]) # still works like a tuple
Sets
Sets store unique values. Order is not guaranteed, and duplicates are automatically removed.
Creation
numbers = {1, 2, 3, 3, 2}
print(numbers) # {1, 2, 3}
empty = set() # correct way to make empty set
Set Operations
| Operation | Example | Result |
|---|---|---|
| Union | {1,2} | {2,3} |
{1,2,3} |
| Intersection | {1,2} & {2,3} |
{2} |
| Difference | {1,2} - {2,3} |
{1} |
| Symmetric Difference | {1,2} ^ {2,3} |
{1,3} |
Frozen Sets
frozenset is an immutable set — useful as dictionary keys or when you want fixed unique values.
fs = frozenset([1, 2, 2, 3])
print(fs) # frozenset({1, 2, 3})
# fs.add(4) # ❌ Error: can't modify frozenset
Dictionaries
Dictionaries store data as key–value pairs. Keys must be unique and immutable (like strings, numbers, tuples), while values can be anything.
Creation
# Literal
user = {"name": "Alice", "age": 25}
# Constructor
data = dict(x=10, y=20)
print(user["name"]) # Alice
Common Methods
| Method | Example | Result |
|---|---|---|
.keys() |
user.keys() |
dict_keys(['name','age']) |
.values() |
user.values() |
dict_values(['Alice',25]) |
.items() |
user.items() |
dict_items([('name','Alice'),('age',25)]) |
.get() |
user.get("name") |
Alice |
.update() |
user.update({"age": 26}) |
{'name':'Alice','age':26} |
.pop() |
user.pop("age") |
25 (removes key) |
Dict Comprehensions
# Square numbers into dict
squares = {x: x**2 for x in range(5)}
print(squares) # {0:0, 1:1, 2:4, 3:9, 4:16}
Nested Dictionaries
users = {
"alice": {"age": 25, "role": "admin"},
"bob": {"age": 30, "role": "editor"}
}
print(users["alice"]["role"]) # admin
Data Structure Comparisons
Python gives us multiple built-in containers. Each has its strengths — choosing the right one can make your code faster and cleaner.
| Structure | Key Properties | Performance Notes | Best Use Cases |
|---|---|---|---|
| List | Ordered, mutable, allows duplicates | Fast append & iteration, slower lookups (O(n)) |
General sequences, dynamic collections |
| Tuple | Ordered, immutable | Lighter & faster than lists, hashable (usable as dict keys) | Fixed data, function returns, safe read-only data |
| Set | Unordered, unique values | Fast membership checks (O(1)), no duplicates |
Removing duplicates, fast lookups, math-like operations |
| Dict | Key–value mapping, keys unique | Fast key lookups & updates (O(1)) |
Configurations, mappings, JSON-like data |
Conditionals
Conditionals let your code make decisions. Python uses if, elif, and else blocks, indented consistently.
x = 10
if x > 0:
print("Positive")
elif x == 0:
print("Zero")
else:
print("Negative")
Ternary Operator
For short decisions, Python has a one-liner form:
age = 20
status = "Adult" if age >= 18 else "Minor"
print(status) # Adult
Loops
Loops let you repeat code. Python has two main loop types: for and while.
for loop
Iterates directly over a sequence (no need for indexes unless you want them).
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
while loop
Runs as long as a condition is True.
count = 3
while count > 0:
print(count)
count -= 1
# prints: 3, 2, 1
range()
The range() function is commonly used with for loops to generate numbers.
for i in range(2, 10, 2): # start=2, stop=10, step=2
print(i)
# Output: 2, 4, 6, 8
for when looping over items, 👉 Use while when looping until a condition is met.Loop Utilities
Python adds helpers that make looping cleaner and more expressive.
enumerate()
Gives both index and value when looping through a sequence.
names = ["Alice", "Bob", "Charlie"]
for idx, name in enumerate(names, start=1):
print(idx, name)
# 1 Alice
# 2 Bob
# 3 Charlie
zip()
Combines multiple sequences element by element.
scores = [90, 85, 78]
for name, score in zip(names, scores):
print(f"{name}: {score}")
# Alice: 90
# Bob: 85
# Charlie: 78
any() and all()
Check conditions across sequences.
nums = [2, 4, 6, 8]
print(any(n % 2 != 0 for n in nums)) # False
print(all(n % 2 == 0 for n in nums)) # True
Loop Control
Special keywords change how loops behave.
for i in range(5):
if i == 2:
continue # skip iteration
if i == 4:
break # exit loop
print(i)
else:
print("Loop finished without break")
| Keyword | Meaning |
|---|---|
break |
Exit the loop immediately |
continue |
Skip the rest of the current iteration |
else |
Runs only if loop wasn’t broken out of |
Pattern Matching (PEP 634)
Python 3.10 introduced match/case for structural pattern matching, similar to switch statements in other languages but more powerful.
def handle_point(pt):
match pt:
case (0, 0):
return "Origin"
case (x, 0):
return f"X-axis at {x}"
case (0, y):
return f"Y-axis at {y}"
case (x, y):
return f"Point ({x}, {y})"
case _:
return "Unknown"
print(handle_point((0, 0))) # Origin
print(handle_point((5, 0))) # X-axis at 5
match/case works with numbers, strings, sequences, and even classes. 👉 Always include case _: as a fallback.Defining Functions
Functions let you group reusable logic. Use def followed by a name, parameters, and an optional return statement.
def greet(name):
return f"Hello, {name}!"
print(greet("Solviyo")) # Hello, Solviyo!
Arguments
Python functions are flexible in how they accept arguments. Here’s a quick overview:
| Type | Example | Notes |
|---|---|---|
| Positional | power(2, 3) |
Order matters |
| Keyword | power(base=2, exp=3) |
Order doesn’t matter |
| Default | def f(x=10) |
Value used if no argument passed |
| *args | def f(*nums) |
Collects extra positional args (tuple) |
| **kwargs | def f(**opts) |
Collects extra keyword args (dict) |
def demo(*args, **kwargs):
print("args:", args)
print("kwargs:", kwargs)
demo(1, 2, 3, a=10, b=20)
# args: (1, 2, 3)
# kwargs: {'a': 10, 'b': 20}
Scope & Closures
Python resolves variable names using the LEGB rule: Local → Enclosing → Global → Built-in.
| Scope | Description |
|---|---|
| Local | Names inside the current function |
| Enclosing | Names in outer (non-global) functions |
| Global | Names at the module level |
| Built-in | Names preloaded by Python (e.g. len) |
Examples
x = "global"
def outer():
msg = "enclosing"
def inner():
nonlocal msg
print(x, msg)
inner()
outer() # global enclosing
Anonymous Functions → Lambdas
Use lambda for short, throwaway functions. Best for one-liners where a full def would be overkill.
square = lambda x: x**2
print(square(5)) # 25
words = ["solviyo", "python", "cheatsheet"]
print(sorted(words, key=lambda w: len(w)))
# ['python', 'solviyo', 'cheatsheet']
def for complex logic.Decorators
Decorators wrap one function with another, adding extra behavior.
| Decorator | Usage |
|---|---|
@staticmethod |
Bind method to class, no self |
@classmethod |
Bind method to class, gets cls |
@property |
Define getter/setter-like methods |
def logger(func):
def wrapper(*args, **kwargs):
print(f"[Solviyo Log] Calling {func.__name__}")
return func(*args, **kwargs)
return wrapper
@logger
def greet(name):
return f"Hello {name}"
print(greet("Python"))
Generators & Iterators
Generators produce items lazily using yield. Iterators expose __iter__() and __next__().
def countdown(n):
while n > 0:
yield n
n -= 1
for num in countdown(3):
print(num)
# 3 2 1
nums = [10, 20, 30]
it = iter(nums)
print(next(it)) # 10
print(next(it)) # 20
Built-in Functional Tools
Python provides built-ins for applying functions across iterables.
| Function | Usage |
|---|---|
map(func, iterable) |
Apply func to each item |
filter(func, iterable) |
Keep items where func returns True |
reduce(func, iterable) |
Accumulate to a single value (from functools) |
zip(*iterables) |
Combine items element-wise |
from functools import reduce
nums = [1, 2, 3, 4]
print(list(map(lambda x: x*2, nums))) # [2, 4, 6, 8]
print(list(filter(lambda x: x%2==0, nums))) # [2, 4]
print(reduce(lambda a,b: a+b, nums)) # 10
print(list(zip("abc", nums))) # [('a',1),('b',2),('c',3)]
Imports
Python imports can be absolute, relative, or use aliases.
| Type | Example | Notes |
|---|---|---|
| Absolute | import math |
Most common; full path |
| Relative | from . import utils |
Within packages; uses dots |
| Aliasing | import numpy as np |
Shorter reference name |
| Selective | from math import sqrt |
Import only what you need |
Built-in Modules
Python comes batteries-included. Here are some must-know modules:
| Module | Use Case | Example |
|---|---|---|
math |
Mathematical functions | math.sqrt(16) → 4.0 |
random |
Random numbers | random.choice([1,2,3]) |
datetime |
Dates & times | datetime.date.today() |
os |
File system, env vars | os.listdir(".") |
sys |
Python runtime info | sys.version |
import math, random, datetime
print(math.factorial(5)) # 120
print(random.randint(1, 10)) # random int
print(datetime.date.today()) # current date
Creating Packages
A package is just a folder with an __init__.py file.
my_project/
│
├── app.py
├── utils/
│ ├── __init__.py
│ ├── math_tools.py
│ └── string_tools.py
# app.py
from utils import math_tools
print(math_tools.add(2, 3))
Virtual Environments
Keep dependencies isolated per project using venv.
python -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windows
pip install installs into the venv, not globally.Dependency Management
Two common ways to lock dependencies:
| File | Purpose | Example |
|---|---|---|
requirements.txt |
Pin exact versions | requests==2.31.0 |
pyproject.toml |
Modern build metadata | [tool.poetry.dependencies] |
# Freeze dependencies
pip freeze > requirements.txt
# Install dependencies
pip install -r requirements.txt
Classes & Objects
In Python, everything is an object. Classes define blueprints for creating objects, bundling attributes (data) and methods (behavior).
Basic Syntax
class Dog:
# class attribute
species = "Canis familiaris"
def __init__(self, name, age):
# instance attributes
self.name = name
self.age = age
def bark(self):
return f"{self.name} says woof!"
# create objects
fido = Dog("Fido", 3)
print(fido.bark()) # Fido says woof!
Attributes & Methods
| Type | Defined | Example |
|---|---|---|
| Class Attribute | Inside class, shared by all objects | species |
| Instance Attribute | Inside __init__, unique to each object |
self.name, self.age |
| Instance Method | Defined with def, uses self |
bark() |
Adding & Accessing Attributes
# add a new attribute dynamically
fido.color = "brown"
print(fido.color) # brown
# access class attribute
print(Dog.species) # Canis familiaris
self to access instance data. 👉 Objects can have attributes added at runtime. 👉 Class attributes are shared unless shadowed by an instance attribute.Inheritance
Inheritance lets a class (child) reuse and extend behavior from another class (parent).
Single Inheritance
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Woof!"
dog = Dog()
print(dog.speak()) # Woof!
Multiple Inheritance
class Walker:
def move(self):
return "Walking"
class Swimmer:
def move(self):
return "Swimming"
class Amphibian(Walker, Swimmer):
pass
frog = Amphibian()
print(frog.move()) # Walking (first base class wins)
Amphibian(Walker, Swimmer), Python searches in Walker → Swimmer → object.Using super()
super() lets child classes call methods from their parent without naming it directly.
class Vehicle:
def __init__(self, brand):
self.brand = brand
class Car(Vehicle):
def __init__(self, brand, model):
super().__init__(brand) # call parent __init__
self.model = model
car = Car("Tesla", "Model S")
print(car.brand, car.model) # Tesla Model S
Types of Inheritance
| Type | Description | Example |
|---|---|---|
| Single | One base class, one child class | Dog(Animal) |
| Multiple | Child inherits from multiple parents | Amphibian(Walker, Swimmer) |
| Multilevel | Child → Parent → Grandparent chain | C → B → A |
| Hierarchical | Multiple children from one parent | Dog(Animal), Cat(Animal) |
Polymorphism
Polymorphism allows different classes to define methods with the same name, but different behavior. This makes code more flexible and extensible.
Method Overriding
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self): # overrides parent method
return "Woof!"
class Cat(Animal):
def speak(self): # overrides parent method
return "Meow!"
animals = [Dog(), Cat()]
for a in animals:
print(a.speak())
# Woof!
# Meow!
Built-in Example
Python’s built-in functions also show polymorphism. The same len() works on strings, lists, tuples, and more:
print(len("Solviyo")) # 7 (string length)
print(len([1, 2, 3])) # 3 (list length)
print(len((10, 20))) # 2 (tuple length)
Key Points
| Concept | Description | Example |
|---|---|---|
| Overriding | Child class redefines a parent method | Dog.speak() |
| Same Interface | Different objects respond to the same method | a.speak() → Dog or Cat |
| Built-in Polymorphism | Functions like len(), iter() |
len("abc"), len([1,2,3]) |
Encapsulation
Encapsulation restricts direct access to an object’s data. In Python, this is done by naming conventions rather than enforced rules.
Public, Protected, Private
class Account:
def __init__(self, user, balance):
self.user = user # public
self._balance = balance # protected (convention)
self.__pin = "1234" # private (name mangling)
def get_balance(self):
return f"{self.user}'s balance: {self._balance}"
def __get_pin(self): # private method
return self.__pin
acc = Account("SolviyoUser", 500)
print(acc.user) # accessible
print(acc._balance) # accessible but discouraged
# print(acc.__pin) # AttributeError
print(acc._Account__pin) # accessible via name mangling (not recommended)
Access Levels
| Level | Convention | Accessibility |
|---|---|---|
| Public | variable |
Fully accessible anywhere |
| Protected | _variable |
Accessible, but meant for internal use only |
| Private | __variable |
Class-internal use (name mangled) |
@property is Python’s idiomatic way to manage controlled access.Using @property
class User:
def __init__(self, name):
self._name = name
@property
def name(self): # getter
return self._name
@name.setter
def name(self, value): # setter
if not value:
raise ValueError("Name cannot be empty")
self._name = value
u = User("Solviyo")
print(u.name) # Solviyo
u.name = "AI" # valid update
Special Methods (Dunder Methods)
Special methods in Python start and end with __ (double underscores). They let you customize how objects behave with built-in functions and operators.
Example: Custom Class with Special Methods
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
def __str__(self): # human-readable
return f"{self.title} by {self.author}"
def __repr__(self): # developer-friendly
return f"Book({self.title!r}, {self.author!r}, {self.pages})"
def __len__(self): # works with len()
return self.pages
def __eq__(self, other): # ==
return self.title == other.title
b1 = Book("Python Tricks", "Solviyo", 250)
b2 = Book("Python Tricks", "Solviyo", 250)
print(str(b1)) # Python Tricks by Solviyo
print(repr(b1)) # Book('Python Tricks', 'Solviyo', 250)
print(len(b1)) # 250
print(b1 == b2) # True
Common Special Methods
| Method | Purpose | Example |
|---|---|---|
__init__ |
Constructor, initialize attributes | Book("Title", "Author", 100) |
__str__ |
User-friendly string | print(obj) |
__repr__ |
Developer string (debugging) | obj in REPL |
__len__ |
Called by len() |
len(obj) |
__eq__ |
Equality check | obj1 == obj2 |
__add__ |
Overload + operator |
obj1 + obj2 |
__iter__, __next__ |
Make class iterable | for x in obj |
__enter__, __exit__ |
Context managers | with obj: |
__str__ is for end users, __repr__ is for developers. 👉 If you only define __repr__, it’s often used as fallback for __str__. 👉 Special methods let your classes feel “native” in Python.Class vs Static Methods
Besides normal instance methods, Python supports class methods and static methods. These are defined using decorators and control how methods access data.
Example
class MathUtils:
pi = 3.14159
def area_of_circle(self, r): # instance method
return self.pi * r * r
@classmethod
def get_pi(cls): # class method
return cls.pi
@staticmethod
def add(x, y): # static method
return x + y
m = MathUtils()
# Instance method (needs object)
print(m.area_of_circle(5)) # 78.53975
# Class method (works via class or object)
print(MathUtils.get_pi()) # 3.14159
# Static method (no access to class/instance data)
print(MathUtils.add(3, 4)) # 7
Comparison
| Method Type | Decorator | First Arg | Access | Use Case |
|---|---|---|---|---|
| Instance | None | self |
Instance attributes & class attributes | Object-specific behavior |
| Class | @classmethod |
cls |
Class attributes (shared across instances) | Factory methods, alternative constructors |
| Static | @staticmethod |
None | No direct access | Utility functions logically tied to class |
@classmethod is great for alternative constructors (e.g., Date.from_string("2025-09-28")). 👉 @staticmethod is just a namespaced function inside the class. 👉 Regular instance methods remain the most common.Dataclasses & Enums
Python provides dataclasses (for simpler class boilerplate) and enums (for named constants). These improve readability and reduce manual code.
Dataclasses
from dataclasses import dataclass
@dataclass
class Book:
title: str
author: str
pages: int = 0
b1 = Book("Python 101", "Solviyo", 250)
print(b1) # Book(title='Python 101', author='Solviyo', pages=250)
Frozen Dataclasses
Frozen dataclasses make instances immutable:
@dataclass(frozen=True)
class Config:
api_key: str
cfg = Config("XYZ-123")
# cfg.api_key = "ABC" # ❌ Error: cannot assign to field
Dataclass Benefits
| Feature | Normal Class | Dataclass |
|---|---|---|
Auto __init__ |
Manual | Generated automatically |
Auto __repr__ |
Manual | Generated automatically |
| Immutability | Manual @property |
frozen=True |
Enums
from enum import Enum, auto
class Status(Enum):
PENDING = auto()
ACTIVE = auto()
INACTIVE = auto()
print(Status.ACTIVE) # Status.ACTIVE
print(Status.ACTIVE.name) # ACTIVE
print(Status.ACTIVE.value) # 2
Enum Use Cases
| Scenario | Why Enums Help |
|---|---|
| Status Flags | Avoids using raw strings ("active", "inactive") |
| Constants | Groups related constants in one class |
| Readability | Self-documenting & safer than magic numbers |
for status in Status. 👉 Use auto() for automatic numbering. 👉 Great for states, categories, or configuration flags.Comprehensions & Context Managers
Comprehensions provide a compact way to build collections, while context managers simplify resource handling. Both improve readability and reduce boilerplate.
List, Dict, Set, and Nested Comprehensions
# List comprehension
squares = [x**2 for x in range(6)]
# [0, 1, 4, 9, 16, 25]
# Dict comprehension
square_dict = {x: x**2 for x in range(6)}
# {0:0, 1:1, 2:4, 3:9, 4:16, 5:25}
# Set comprehension
unique_lengths = {len(word) for word in ["solviyo", "python", "ai", "python"]}
# {2, 6, 7}
# Nested comprehension (matrix)
matrix = [[i*j for j in range(3)] for i in range(3)]
# [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
When to Use Comprehensions
| Case | Use Loop | Use Comprehension |
|---|---|---|
| Complex logic | ✔️ Clearer with if/else blocks | ❌ Can reduce readability |
| Simple transformation | ❌ Verbose | ✔️ Concise & faster |
| Readability | ✔️ For beginners | ✔️ For short, clean expressions |
Context Managers
# Built-in context manager
with open("solviyo.txt", "w") as f:
f.write("Python Cheat Sheets are awesome!")
# Custom context manager
class SolviyoLogger:
def __enter__(self):
print("Start logging...")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Stop logging...")
with SolviyoLogger():
print("Inside the block")
with ensures cleanup automatically (like closing files). 👉 Use custom context managers for logging, locks, or resources. 👉 Reduces chances of resource leaks and errors.Advanced Python Modules
Python’s standard library provides powerful built-in modules for data processing and performance. Here we explore itertools, functools, and collections with practical examples.
Itertools Module
itertools helps with efficient looping and combinatorial problems.
from itertools import combinations, permutations, product
# Combinations (order doesn't matter)
print(list(combinations([1,2,3], 2)))
# [(1, 2), (1, 3), (2, 3)]
# Permutations (order matters)
print(list(permutations([1,2,3], 2)))
# [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
# Cartesian product
print(list(product([1,2], ['a','b'])))
# [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
combinations for subsets, permutations when order matters, and product for multi-set pairing. 👉 Extremely useful in algorithms, games, and test case generation.Functools Module
functools provides tools for higher-order functions and performance optimization.
from functools import lru_cache, partial, reduce
# lru_cache for memoization
@lru_cache(maxsize=100)
def fib(n):
if n < 2: return n
return fib(n-1) + fib(n-2)
print(fib(30)) # Cached calls improve performance
# partial: pre-filling arguments
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
print(square(5)) # 25
# reduce: cumulative function
nums = [1, 2, 3, 4]
total = reduce(lambda x, y: x + y, nums)
print(total) # 10
lru_cache improves recursive performance. 👉 partial helps create specialized versions of functions. 👉 reduce applies a function cumulatively (like sum/product).Collections Module
collections offers specialized containers beyond dicts and lists.
from collections import Counter, defaultdict, deque, OrderedDict
# Counter
cnt = Counter("solviyo loves python")
print(cnt.most_common(3)) # [('o', 3), (' ', 2), ('s', 2)]
# defaultdict
dd = defaultdict(int)
dd['missing'] += 1
print(dd) # defaultdict(, {'missing': 1})
# deque (fast appends & pops from both ends)
dq = deque([1,2,3])
dq.appendleft(0)
print(dq) # deque([0,1,2,3])
# OrderedDict (preserves insertion order, Python 3.6+ dict does too)
od = OrderedDict()
od['a'] = 1
od['b'] = 2
print(list(od.keys())) # ['a','b']
| Class | Use Case |
|---|---|
Counter |
Counting frequencies (e.g., words, items) |
defaultdict |
Avoids KeyError, auto-creates default values |
deque |
Fast queue/stack operations on both ends |
OrderedDict |
Preserve insertion order (historically before dict did) |
collections when default Python containers feel limited. 👉 Counter is excellent for quick statistics. 👉 deque outperforms lists for frequent appends/pops from both ends.Typing, Async & Metaprogramming
Modern Python supports type hints for clarity, async/await for concurrency, and metaprogramming for dynamic code. These advanced tools help make code more reliable, scalable, and flexible.
Typing & Type Hints
Type hints improve readability, catch bugs earlier (via tools like mypy), and enable better IDE support.
from typing import List, Union, Optional
def greet(name: str, age: Optional[int] = None) -> str:
if age:
return f"Hello {name}, you are {age} years old."
return f"Hello {name}!"
def add(values: List[int]) -> int:
return sum(values)
def combine(x: Union[int, str], y: Union[int, str]) -> str:
return str(x) + str(y)
Union = multiple possible types. 👉 Optional[X] = either X or None. 👉 List[int] = generics notation.Async & Await
Python uses async and await for concurrent programming with an event loop. Ideal for I/O-bound tasks like web requests, DB queries, or file operations.
import asyncio
async def fetch_data():
print("Fetching data...")
await asyncio.sleep(2)
return {"source": "Solviyo", "data": [1,2,3]}
async def main():
result = await fetch_data()
print(result)
asyncio.run(main())
| Concept | Description |
|---|---|
async def |
Defines a coroutine function |
await |
Pauses until coroutine/task is complete |
asyncio.run() |
Runs an event loop until finished |
Metaprogramming
Metaprogramming lets Python code generate or modify code dynamically. Use with caution for advanced use cases.
# type(): create classes dynamically
MyClass = type("MyClass", (), {"x": 42})
obj = MyClass()
print(obj.x) # 42
# Metaclasses: control class creation
class Meta(type):
def __new__(cls, name, bases, attrs):
attrs["tag"] = "CreatedBySolviyo"
return super().__new__(cls, name, bases, attrs)
class Demo(metaclass=Meta):
pass
print(Demo.tag) # CreatedBySolviyo
# eval / exec: run code strings (use cautiously!)
code = "print('Hello from exec at Solviyo!')"
exec(code)
type() can build classes on the fly. 👉 Metaclasses are advanced — great for frameworks & ORMs. 👉 eval/exec are powerful but risky — avoid with untrusted input.Files & Persistence
Python provides powerful tools for working with files and structured data formats like JSON and CSV. Proper handling ensures reliability and prevents resource leaks.
File Handling
Use the built-in open() function for reading and writing files. Always prefer context managers (with) for automatic closing.
# Writing to a file
with open("solviyo_notes.txt", "w") as f:
f.write("Learning Python with Solviyo!")
# Reading from a file
with open("solviyo_notes.txt", "r") as f:
content = f.read()
print(content)
JSON Handling
JSON (JavaScript Object Notation) is widely used for data exchange. Python’s json module makes serialization and deserialization simple.
import json
# Writing JSON
data = {"site": "Solviyo", "language": "Python"}
with open("data.json", "w") as f:
json.dump(data, f)
# Reading JSON
with open("data.json", "r") as f:
loaded = json.load(f)
print(loaded)
CSV Handling
CSV (Comma-Separated Values) is common for tabular data. Use the csv module for reading and writing.
import csv
# Writing CSV
rows = [["Name", "Score"], ["Alice", 90], ["Bob", 85]]
with open("scores.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerows(rows)
# Reading CSV
with open("scores.csv", "r") as f:
reader = csv.reader(f)
for row in reader:
print(row)
When to Use
| Format | Use Case |
|---|---|
| Plain Text | Simple notes, logs, or unstructured data |
| JSON | APIs, configs, structured but lightweight data |
| CSV | Tabular data, spreadsheets, interoperability |
with) to prevent memory leaks. 👉 For large JSON/CSV files, consider streaming or chunked reading. 👉 Ensure file encoding (UTF-8 recommended) for cross-platform compatibility.Error Handling & Debugging
Python uses exceptions to signal errors. Understanding how to handle and raise exceptions properly makes your programs more reliable and easier to debug.
Try / Except / Else / Finally
Wrap risky code in try. Use except for handling, else for success cases, and finally for cleanup.
try:
num = int("10a")
except ValueError:
print("Invalid number!")
else:
print("Conversion successful")
finally:
print("Execution finished")
Common Exceptions
Python raises built-in exceptions for common errors. Some useful ones include:
| Exception | When it Occurs |
|---|---|
ValueError |
Wrong value (e.g., int("abc")) |
TypeError |
Invalid operation on data types ("2" + 2) |
KeyError |
Accessing missing dict keys |
IndexError |
Index out of range in a list |
ZeroDivisionError |
Dividing by zero |
Raising Exceptions
Use raise to signal errors intentionally. You can also create custom exceptions by subclassing Exception.
# Raising a built-in exception
def divide(a, b):
if b == 0:
raise ZeroDivisionError("Division by zero is not allowed")
return a / b
# Custom exception
class SolviyoError(Exception):
pass
def check_value(x):
if x < 0:
raise SolviyoError("Negative values not supported")
check_value(-5)
ValueError, KeyError) instead of a bare except. 👉 Add descriptive messages when raising errors. 👉 Keep custom exceptions meaningful and project-specific.Practice Python After Reading
Now that you’ve explored the Python Cheat Sheet, test your knowledge and sharpen your skills: