>>> Python Quick Reference Syntax · Functions · Methods · Stdlib · Examples

01 Basics

python.basics

Core building blocks: comments, variables, naming, I/O, and every operator category. Reference covers Python 3.12+ (notes flag anything version-specific).

Comments

# single-line comment

"""
Multi-line string used
as a block comment (not a true comment,
but the common convention)
"""

Variables & multiple assignment

x = 10                 # dynamic typing, no declaration keyword
name = "Rushit"

a, b, c = 1, 2, 3       # multiple assignment
x = y = z = 0           # chained assignment
a, b = b, a             # swap without a temp variable

Constants & naming conventions

MAX_SIZE = 100          # convention only — Python has no true constants
PI = 3.14159

# naming conventions
variable_name = 1       # snake_case for variables/functions
class ClassName: ...    # PascalCase for classes
_private = 1            # leading underscore: "internal use" hint
__very_private = 1      # name-mangled inside classes
__dunder__ = 1          # reserved for language/magic methods

Input / Output

name = input("Enter name: ")   # ALWAYS returns a str
age = int(input("Age: "))     # convert manually if you need a number

print("Hello", name, sep=", ", end="!\n")
print(f"{name} is {age}")     # f-string (see Strings section)
noteprint(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Type conversion & inspection

Conversion functions (int(), float(), str(), list()…) are documented as built-ins below. Quick inspection tools:

type(3.14)                 # -> <class 'float'>
isinstance(3.14, float)     # -> True
isinstance(3, (int, float)) # -> True (tuple of types allowed)
id(name)                    # -> unique memory identity (int)
help(str.split)             # -> interactive docs in the REPL
dir(list)                   # -> list of all attributes/methods

Operators

Arithmetic
OpMeaningExampleResult
+Add5 + 27
-Subtract5 - 23
*Multiply5 * 210
/True division (always float)5 / 22.5
//Floor division5 // 22
%Modulo (remainder)5 % 21
**Exponent5 ** 225
Comparison & Logical
OpMeaningExampleResult
== !=Equal / not equal3 == 3True
> < >= <=Ordering5 >= 5True
andBoth truthyTrue and FalseFalse
orEither truthyTrue or FalseTrue
notNegationnot TrueFalse
Assignment
OpSame as
+= -= *= /=x = x + y, etc.
//= %= **=floor-div / mod / power, in place
&= |= ^= >>= <<=bitwise, in place
Bitwise (operate on integer bit patterns)
OpMeaningExampleResult
&AND6 & 32
|OR6 | 37
^XOR6 ^ 35
~NOT (invert bits)~6-7
<<Left shift1 << 38
>>Right shift8 >> 22
Membership & Identity
OpMeaningExample
inValue exists in container3 in [1,2,3]
not inValue absent5 not in [1,2,3]
isSame object identity (not equality)a is b
is notDifferent identitya is not None

Operator precedence (high → low, abridged)

()                         # grouping
**                         # exponent (right-assoc)
+x -x ~x                   # unary
*  /  //  %
+  -
<<  >>
&
^
|
==  !=  <  >  <=  >=  is  is not  in  not in
not
and
or
:=  (walrus, lowest — used as an expression)
When in doubt, use parentheses — precedence bugs are hard to spot on re-read.

Walrus operator := 3.8+

Assigns and returns a value in the same expression — useful in while/if conditions and comprehensions.

# without walrus
data = get_data()
while data:
    process(data)
    data = get_data()

# with walrus
while (data := get_data()):
    process(data)

# in a comprehension
results = [y for x in values if (y := transform(x)) is not None]

02 Built-in Functions

python.builtins — docs.python.org/3/library/functions.html

All 69 built-ins always available with no import. Search above or scan cards below — each shows syntax, parameters, a working example, and its official doc link.

03 Strings

python.str

Strings are immutable sequences of Unicode code points.

Creating strings

'single quotes'
"double quotes"
'''triple single —
   spans multiple lines'''
"""triple double — same, and the
   convention for docstrings"""

r"raw string — \n is two chars, not a newline"   # great for regex / Windows paths
f"f-string — inline {1 + 1} expressions"          # see below

Indexing, slicing & core operations

s = "Python"
s[0]        # 'P'            (indexing)
s[-1]       # 'n'            (negative indexing, from the end)
s[1:4]      # 'yth'          (slicing: start:stop, stop excluded)
s[::-1]     # 'nohtyP'       (reverse via step -1)
s[::2]      # 'Pto'          (every 2nd char)

s + "3"     # 'Python3'      (concatenation)
s * 2       # 'PythonPython' (repetition)
'y' in s    # True           (membership)
s == "Python"  # True        (comparison, case-sensitive)

f-strings & format specifiers

name, pi = "Rushit", 3.14159
f"{name} scored {pi:.2f}"     # -> 'Rushit scored 3.14'   (2 decimal places)
f"{42:05d}"                   # -> '00042'                (zero-padded width 5)
f"{1234567:,}"                # -> '1,234,567'            (thousands separator)
f"{pi:>10.2f}"                # -> '      3.14'            (right-align, width 10)
f"{name=}"                    # -> "name='Rushit'"        (debug spec, 3.8+)

Escape characters & multiline

"Line1\nLine2"     # \n newline, \t tab, \\ backslash, \' \" quotes
"""
This spans
multiple physical lines
"""

String methods

04 Lists

python.list — mutable, ordered sequence

Creating & core operations

nums = [1, 2, 3]
mixed = [1, "two", 3.0, [4, 5]]     # nested list
empty = []

nums[0]          # 1              indexing
nums[-1]         # 3              negative indexing
nums[0:2]        # [1, 2]         slicing
nested = [[1,2],[3,4]]
nested[1][0]     # 3              nested access

a, b, c = nums              # unpacking
first, *rest = nums         # first=1, rest=[2, 3]

[1,2] + [3,4]    # [1, 2, 3, 4]   concatenation
[1,2] * 3        # [1,2,1,2,1,2]  repetition
2 in nums        # True           membership

List methods

sorted() vs .sort()

nums = [3, 1, 2]
new_list = sorted(nums)     # returns a NEW sorted list; nums unchanged
nums.sort()                 # sorts IN PLACE; returns None (common bug: x = nums.sort())

Shallow copy vs reference

a = [1, 2, 3]
b = a              # reference — b and a point to the SAME list
b.append(4)        # a is now [1, 2, 3, 4] too!

c = a.copy()       # or list(a), or a[:] — shallow copy, new outer list
c.append(5)        # a is unaffected

import copy
d = copy.deepcopy(a)   # needed when a contains nested mutable objects

List comprehensions

squares = [x**2 for x in range(6)]                 # [0,1,4,9,16,25]
evens   = [x for x in range(10) if x % 2 == 0]     # conditional
grid    = [[r*3+c for c in range(3)] for r in range(3)]  # nested
tagged  = ["even" if x%2==0 else "odd" for x in range(4)] # if/else expr form
see alsofull Comprehensions section (09) for dict/set/generator forms

05 Tuples

python.tuple — immutable, ordered sequence

t = (1, 2, 3)
single = (5,)          # the COMMA makes it a tuple, not the parens
not_a_tuple = (5)      # this is just int 5

t[0]            # 1            indexing
t[1:]           # (2, 3)       slicing
nested = (1, (2, 3), [4, 5])

a, b, c = t              # unpacking
first, *rest = t         # first=1, rest=[2, 3]

t.count(2)      # 1            only 2 methods exist: count, index
t.index(3)      # 2
Tuple vs List
TupleList
MutableNoYes
Syntax(1, 2)[1, 2]
Methodscount, index11 methods (append, sort, …)
HashableYes (if elements are)No — can't be a dict key
Typical useFixed records, dict keys, function returnsGrowing collections

06 Sets

python.set — unordered, unique elements

s = {1, 2, 3}
empty = set()          # NOT {} — that creates an empty dict!
s.add(4)
s.remove(1)             # KeyError if missing
s.discard(99)           # no error if missing

a, b = {1,2,3}, {2,3,4}
a | b     # union                -> {1,2,3,4}
a & b     # intersection         -> {2,3}
a - b     # difference           -> {1}
a ^ b     # symmetric difference -> {1,4}
a <= b    # subset?              -> False
a >= b    # superset?            -> False
a.isdisjoint(b)          # False (they share elements)

evens = {x for x in range(10) if x % 2 == 0}   # set comprehension
frozen = frozenset([1, 2, 3])                   # immutable, hashable set

Set methods

07 Dictionaries

python.dict — key-value mapping, insertion-ordered (3.7+)

d = {"name": "Rushit", "year": 2}
d["name"]          # 'Rushit'       access (KeyError if missing)
d.get("gpa")       # None           .get() — safe, no KeyError
d.get("gpa", 0.0)  # 0.0            .get() with default

d["year"] = 3            # update
d["branch"] = "CS"       # add new key
del d["branch"]           # remove
d.pop("year")             # remove + return value

nested = {"student": {"name": "Rushit", "skills": ["Python", "SQL"]}}
nested["student"]["skills"]

merged = {**d, **{"gpa": 8.5}}   # dict unpacking merge (or d | other, 3.9+)

d.keys()      # view of keys (dict_keys)
d.values()    # view of values
d.items()     # view of (key, value) pairs

Dictionary methods

Comprehension & iteration patterns

squares = {x: x**2 for x in range(5)}          # dict comprehension

for k in d: ...                    # iterates keys
for k in d.keys(): ...             # same, explicit
for v in d.values(): ...           # iterates values
for k, v in d.items(): ...         # iterates pairs (most common)

08 Control Flow

python.control_flow

if score >= 90:
    grade = "A"
elif score >= 75:
    grade = "B"
else:
    grade = "C"

grade = "A" if score >= 90 else "B"     # ternary / conditional expression

for i in range(5):          # 0..4
    if i == 3:
        break                # exit loop entirely
    if i == 1:
        continue             # skip to next iteration
    print(i)
else:
    print("loop finished without break")   # runs only if no break

while attempts < 3:
    attempts += 1
else:
    print("while finished without break")

if debug:
    pass                     # no-op placeholder

match / case 3.10+

match command.split():
    case ["go", direction] if direction in ("n","s","e","w"):
        move(direction)
    case ["go", _]:
        print("unknown direction")
    case ["quit"]:
        exit()
    case _:
        print("unrecognized command")     # wildcard / default

09 Comprehensions

python.comprehensions — loop, condition and expression fused into one line

# normal approach
squares = []
for x in range(10):
    squares.append(x**2)

# comprehension approach
squares = [x**2 for x in range(10)]

# list comprehension with condition
evens = [x for x in range(10) if x % 2 == 0]

# nested list comprehension (flatten a 2D grid)
grid = [[1,2],[3,4]]
flat = [n for row in grid for n in row]        # [1, 2, 3, 4]

# dict comprehension
squares_map = {x: x**2 for x in range(5)}

# set comprehension
unique_lengths = {len(w) for w in ["hi","bye","yo"]}

# generator expression — lazy, computed one item at a time, no [] brackets
gen = (x**2 for x in range(10**6))     # doesn't build the whole list in memory
sum(x**2 for x in range(10))            # generator expr passed directly to sum()

10 Functions

python.functions

Defining & calling

def greet(name, greeting="Hello"):
    """Return a greeting string. (this is a docstring)"""
    return f"{greeting}, {name}!"

greet("Rushit")                    # positional argument -> uses default greeting
greet("Rushit", greeting="Hi")     # keyword argument
greet(name="Rushit", greeting="Hi")

Parameter kinds compared

def f(a, b):            # positional or keyword — most common
    ...

def f(a, b=10):         # default argument — evaluated ONCE at def time (careful with mutables)
    ...

def f(*args):           # collects extra positional args into a tuple
    ...

def f(**kwargs):        # collects extra keyword args into a dict
    ...

def f(a, /, b, *, c):   # a = positional-only, b = either, c = keyword-only
    ...                 #   /  marks end of positional-only section
                         #   *  marks start of keyword-only section

def f(a, b, *args, c, **kwargs):   # realistic mix, all forms together
    ...

Return values

def divmod_(a, b):
    return a // b, a % b       # multiple return values -> packed as a tuple

q, r = divmod_(17, 5)          # unpacked on the caller's side -> q=3, r=2

Annotations, scope & closures

def add(a: int, b: int) -> int:    # annotations — hints only, not enforced at runtime
    return a + b

count = 0
def increment():
    global count            # without this, count += 1 below raises UnboundLocalError
    count += 1

def outer():
    total = 0
    def inner(x):
        nonlocal total       # modifies the ENCLOSING function's variable, not global
        total += x
    inner(5)
    return total

def make_multiplier(n):      # closure: inner() "remembers" n after make_multiplier returns
    def multiplier(x):
        return x * n
    return multiplier
times3 = make_multiplier(3)
times3(10)                    # -> 30

Recursion, first-class & higher-order functions

def factorial(n):
    return 1 if n <= 1 else n * factorial(n - 1)     # recursion

def apply_twice(fn, x):        # functions are first-class: pass them like any value
    return fn(fn(x))
apply_twice(lambda x: x*2, 3)   # -> 12  (higher-order function: takes a function as arg)

11 Lambda & Functional Programming

python.functional

square = lambda x: x ** 2          # anonymous, single-expression function
square(5)                           # -> 25

list(map(lambda x: x*2, [1,2,3]))          # [2, 4, 6]
list(filter(lambda x: x % 2 == 0, range(10)))  # [0, 2, 4, 6, 8]

from functools import reduce
reduce(lambda acc, x: acc + x, [1,2,3,4])   # -> 10  (running accumulation)

list(zip([1,2,3], ['a','b','c']))           # [(1,'a'), (2,'b'), (3,'c')]
list(enumerate(['a','b','c'], start=1))      # [(1,'a'), (2,'b'), (3,'c')]

any(x > 5 for x in [1,2,8])       # True  — at least one truthy
all(x > 0 for x in [1,2,8])       # True  — every element truthy

Realistic combinations

data = [("Rushit", 82), ("Aman", 91), ("Zoya", 76)]

sorted(data, key=lambda x: x[1])              # sort by score ascending
sorted(data, key=lambda x: x[1], reverse=True) # descending
max(data, key=lambda x: x[1])                  # ('Aman', 91)
min(data, key=lambda x: x[1])                  # ('Zoya', 76)

12 Iterators & Generators

python.iterators

Iterable  ->  has __iter__()          e.g. a list, tuple, str, dict
Iterator  ->  has __next__() AND __iter__()  e.g. what iter(list) produces

nums = [1, 2, 3]      # iterable, not itself an iterator
it = iter(nums)        # -> iterator object
next(it)               # 1
next(it)               # 2
next(it)               # 3
next(it)               # raises StopIteration — the loop-ending signal

Generator functions (yield)

def countdown(n):
    while n > 0:
        yield n            # pauses here, resumes on next next() call
        n -= 1

for x in countdown(3):     # 3, 2, 1 — computed lazily, one at a time
    print(x)

def chain_gen():
    yield from countdown(2)   # delegate to another generator/iterable
    yield from [10, 20]
list(chain_gen())            # [2, 1, 10, 20]

gen_expr = (x**2 for x in range(5))   # generator expression, same laziness as yield
why it mattersgenerators produce values on demand instead of building a full list in memory — key for large datasets / streaming data

13 Object-Oriented Programming

python.oop

class Student:
    school = "Nirma University"          # class attribute — shared by all instances

    def __init__(self, name, gpa):        # constructor
        self.name = name                  # instance attribute
        self.gpa = gpa

    def summary(self):                    # instance method — needs self
        return f"{self.name}: {self.gpa}"

    @classmethod
    def from_string(cls, data):           # class method — receives the class (cls)
        name, gpa = data.split(",")
        return cls(name, float(gpa))

    @staticmethod
    def is_passing(gpa):                  # static method — no self/cls, just grouped in the class
        return gpa >= 5.0

    @property
    def status(self):                     # property — call like an attribute, no ()
        return "Good standing" if self.gpa >= 7 else "At risk"

s = Student("Rushit", 8.5)
s.summary()
Student.from_string("Aman,7.2")
Student.is_passing(6.0)
s.status                # no parentheses — properties act like read-only attributes

Inheritance & polymorphism

class Person:
    def __init__(self, name):
        self.name = name
    def greet(self):
        return f"Hi, I'm {self.name}"

class Student(Person):                 # single inheritance
    def __init__(self, name, roll_no):
        super().__init__(name)          # call the parent's __init__
        self.roll_no = roll_no
    def greet(self):                    # method overriding
        return super().greet() + f" ({self.roll_no})"

class TA(Student, Person):              # multiple inheritance (MRO decides lookup order)
    pass

for p in [Person("A"), Student("B", 1)]:
    print(p.greet())                    # polymorphism — same call, different behavior

Encapsulation & abstract classes

class Account:
    def __init__(self, balance):
        self._balance = balance          # "protected" convention (single underscore)
        self.__pin = 1234                # "private" convention (name-mangled)

from abc import ABC, abstractmethod
class Shape(ABC):
    @abstractmethod
    def area(self):                      # subclasses MUST implement this
        ...

class Circle(Shape):
    def __init__(self, r): self.r = r
    def area(self): return 3.14159 * self.r ** 2

Shape()      # TypeError — can't instantiate an abstract class directly

Common dunder (magic) methods

MethodTriggered by
__init__(self, ...)Object creation — the constructor
__str__(self)str(obj) / print(obj) — readable form
__repr__(self)repr(obj) — unambiguous, debug-friendly form
__len__(self)len(obj)
__getitem__(self,k)obj[k]
__setitem__(self,k,v)obj[k] = v
__iter__(self)Makes the object iterable (for x in obj)
__next__(self)next(obj) when obj is an iterator
__eq__(self, other)obj == other
__lt__(self, other)obj < other
__add__(self, other)obj + other
__enter__ / __exit__with obj: — context manager protocol

14 Exception Handling

python.exceptions

try:
    result = 10 / divisor
except ZeroDivisionError:
    result = 0
except (TypeError, ValueError) as e:      # multiple exceptions + alias
    print(f"bad input: {e}")
else:
    print("ran only if no exception was raised")
finally:
    print("always runs — cleanup goes here")

raise ValueError("gpa must be between 0 and 10")   # raise manually

class InvalidGPAError(Exception):          # custom exception
    pass
raise InvalidGPAError("gpa out of range")

Exception quick reference

ExceptionUsually happens whenExample
ExceptionBase class for (almost) all built-in exceptionsexcept Exception as e:
ValueErrorRight type, invalid valueint("abc")
TypeErrorWrong type used in an operation"2" + 2
IndexErrorSequence index out of range[1,2][5]
KeyErrorDict key doesn't exist{}["x"]
FileNotFoundErrorPath doesn't exist on diskopen("missing.txt")
ZeroDivisionErrorDividing by zero5 / 0
AttributeErrorAttribute/method doesn't exist"x".push()
ImportErrorName can't be imported from a modulefrom math import fake
ModuleNotFoundErrorModule itself doesn't existimport fakemodule

15 File Handling

python.files

with open("data.txt", "r") as f:     # ALWAYS prefer 'with' — see why below
    content = f.read()                # whole file as one string
    # f.readline()                    # one line at a time
    # f.readlines()                   # list of all lines

with open("data.txt", "w") as f:      # 'w' overwrites the whole file
    f.write("first line\n")
    f.writelines(["second\n", "third\n"])

with open("data.txt", "a") as f:      # 'a' appends without erasing
    f.write("appended line\n")

with open("data.txt") as f:
    f.seek(0)                          # move cursor to byte offset
    pos = f.tell()                     # current cursor position
File modes
ModeMeaning
'r'Read (default) — errors if file doesn't exist
'w'Write — creates file, truncates if it exists
'a'Append — creates file if missing, adds to the end
'x'Exclusive create — errors if the file already exists
'b'Binary mode suffix, e.g. 'rb', 'wb'
'+'Read and write, e.g. 'r+'
Why with: it calls f.close() automatically — even if an exception happens inside the block — so file handles never leak.

16 Modules & Imports

python.modules

import math                    # whole module -> use as math.sqrt()
from math import sqrt          # just one name -> use as sqrt()
from math import *             # everything (avoid — pollutes namespace, unclear origin)
import numpy as np             # aliased import — very common convention

# your own module: save as helpers.py, then anywhere in the same project:
import helpers
helpers.my_function()

if __name__ == "__main__":     # True only when this file is run directly,
    main()                       # False when it's imported by another file
# package layout
myproject/
├── main.py
└── mypackage/
    ├── __init__.py
    └── utils.py

# inside main.py
from mypackage import utils
from mypackage.utils import helper_fn
from . import utils              # relative import — only inside a package

import sys
sys.path                          # list of directories Python searches for modules
sys.path.append("/custom/path")   # add a directory at runtime
# command line — package management
pip install pandas
pip install pandas==2.2.0
pip freeze > requirements.txt     # snapshot installed packages
pip install -r requirements.txt    # install from that snapshot

python -m venv .venv                # create a virtual environment
.venv\Scripts\activate              # activate on Windows
source .venv/bin/activate           # activate on macOS/Linux

17 Standard Library

python.stdlib — the modules used most in data work, scripting & backend code

18 Regular Expressions

python.re — docs.python.org/3/library/re.html

import re

re.search(r"\d+", "room 42")        # -> Match object at first occurrence, or None
re.match(r"\d+", "42 room")          # -> matches only at the START of the string
re.fullmatch(r"\d+", "42")           # -> matches only if the WHOLE string fits
re.findall(r"\d+", "a1 b22 c333")    # -> ['1', '22', '333']  (all matches, as strings)
re.finditer(r"\d+", "a1 b22")        # -> iterator of Match objects (has .start()/.end())
re.sub(r"\d+", "#", "room 42")       # -> 'room #'  (replace matches)
re.split(r"\s+", "a   b  c")         # -> ['a', 'b', 'c']  (split on a pattern)

pattern = re.compile(r"\d+")         # pre-compile for reuse in a loop (faster)
pattern.findall("a1 b22")
Character classes & quantifiers
TokenMeaning
\d \Ddigit / non-digit
\w \Wword char (letter/digit/_) / non-word
\s \Swhitespace / non-whitespace
.any char except newline
[abc] [^abc]one of a/b/c / none of a/b/c
* + ?0+, 1+, 0-or-1 of the previous token
{n,m}between n and m repetitions
^ $start / end of string (anchors)
(...)capturing group — retrievable via .group(1)
(?:...)non-capturing group

Common patterns

email    = r"[\w.+-]+@[\w-]+\.[\w.-]+"
phone_in = r"\d{10}"                        # simple 10-digit number
digits   = r"\d+"
whitespace = r"\s+"

# extracting numbers from mixed text
re.findall(r"\d+\.?\d*", "Price: 199.99, Qty: 3")   # ['199.99', '3']

# finding whole words only (word boundary)
re.findall(r"\bcat\b", "cat category concatenate")   # ['cat']

# always use RAW strings for patterns — avoids \d becoming an invalid escape

19 Date & Time

python.datetime

from datetime import date, time, datetime, timedelta

date.today()                       # date(2026, 8, 2) — today's date, no time
datetime.now()                      # datetime(2026, 8, 2, 14, 30, 5, ...)
time(14, 30)                        # time object, 2:30 PM, no date attached

datetime.now() + timedelta(days=7)       # a week from now
datetime.now() - timedelta(hours=3)      # 3 hours ago
d1, d2 = date(2026,1,1), date(2026,8,2)
(d2 - d1).days                            # -> 213 (difference as a timedelta)

now = datetime.now()
now.strftime("%Y-%m-%d %H:%M:%S")         # datetime -> string
datetime.strptime("2026-08-02", "%Y-%m-%d")  # string -> datetime
Common format codes (used in strftime / strptime)
CodeMeaningExample
%Y4-digit year2026
%y2-digit year26
%mmonth (01-12)08
%dday of month02
%Hhour, 24h (00-23)14
%Ihour, 12h (01-12)02
%Mminute30
%Ssecond05
%A / %aweekday name / abbreviatedSunday / Sun
%B / %bmonth name / abbreviatedAugust / Aug
%pAM/PMPM

20 Python Data Handling Patterns

python.patterns — the snippets you reach for constantly

21 Syntax at a Glance

python.syntax_index — every core construct, compressed to its shape

22 Decorators

python.decorators — a function that wraps another function

def logger(func):                 # a decorator is just a function...
    def wrapper(*args, **kwargs):  # ...that returns a wrapper function
        print(f"calling {func.__name__}")
        result = func(*args, **kwargs)
        print(f"done: {result}")
        return result
    return wrapper

@logger                            # sugar for: greet = logger(greet)
def greet(name):
    return f"Hi {name}"

greet("Rushit")   # prints the log lines, then returns "Hi Rushit"
from functools import wraps

def logger(func):
    @wraps(func)                   # preserves func.__name__ / __doc__ on the wrapper
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@logger
@staticmethod                      # stacking decorators — applied bottom-up
def utility(): ...
notewithout @wraps, greet.__name__ becomes "wrapper" instead of "greet" — breaks introspection/docs

23 Context Managers

python.context_managers — guaranteed setup / teardown around a block

with open("f.txt") as f:      # the classic example — guarantees f.close()
    data = f.read()

class Timer:                    # writing your own — implement __enter__/__exit__
    def __enter__(self):
        import time
        self.start = time.time()
        return self                   # value bound to "as x"
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"took {time.time() - self.start:.4f}s")
        return False                  # False -> don't suppress exceptions

with Timer() as t:
    do_something_slow()

from contextlib import contextmanager
@contextmanager                      # simpler way, using a generator
def timer():
    import time
    start = time.time()
    yield                              # code inside the "with" block runs here
    print(f"took {time.time() - start:.4f}s")

with timer():
    do_something_slow()
Why bother: cleanup (closing files, releasing locks, closing DB connections) runs even if the block raises an exception.

24 Type Hints

python.typing — hints only, not enforced at runtime (use mypy/pyright to check)

x: int = 5
name: str = "Rushit"
numbers: list[int] = [1, 2, 3]              # modern generic syntax (3.9+)
data: dict[str, int] = {"a": 1}
point: tuple[int, str] = (1, "x")
maybe_name: int | None = None                # union, modern syntax (3.10+)

def add(a: int, b: int) -> int:              # param + return annotations
    return a + b

from typing import Optional, Union, Any, Callable, TypeVar, TypedDict

def find(x: int) -> Optional[str]: ...        # same as -> str | None
def parse(x: Union[int, str]) -> Any: ...     # same as int | str (pre-3.10 style)

on_click: Callable[[int, int], None]           # a function taking (int,int) -> None

T = TypeVar("T")
def first(items: list[T]) -> T:                # generic function — works for any type
    return items[0]

class Movie(TypedDict):                        # dict with a fixed, typed shape
    title: str
    year: int

25 Dataclasses

python.dataclasses — auto-generates __init__, __repr__, __eq__ from field annotations

from dataclasses import dataclass, field

@dataclass
class Student:
    name: str
    gpa: float = 0.0                       # default value
    skills: list[str] = field(default_factory=list)   # mutable default — needs field()

s = Student("Rushit", 8.5, ["Python", "SQL"])
print(s)                    # Student(name='Rushit', gpa=8.5, skills=['Python', 'SQL'])
s == Student("Rushit", 8.5, ["Python", "SQL"])   # True — __eq__ generated for free

@dataclass(frozen=True)      # immutable — raises on attribute assignment after creation
class Point:
    x: int
    y: int

26 Async Python

python.asyncio — concurrency for I/O-bound work (network calls, file/database I/O)

import asyncio

async def fetch(id):                 # 'async def' -> defines a coroutine function
    await asyncio.sleep(1)            # 'await' -> pause here, let other tasks run
    return f"result {id}"

async def main():
    result = await fetch(1)           # run one coroutine and wait for it

    task = asyncio.create_task(fetch(2))    # schedule concurrently, keep running
    other_result = await task

    results = await asyncio.gather(fetch(3), fetch(4), fetch(5))  # run several at once

asyncio.run(main())                    # entry point — starts the event loop
When it helps: waiting on many network requests / API calls / DB queries at once. It does not speed up CPU-heavy work (use multiprocessing for that instead).

27 Special Syntax & Operators

python.operators — the symbols that trip people up out of context

SymbolMeaningExample
*Unpack iterable into positional args / collect extra positional argsf(*args) · a, *rest = [1,2,3]
**Unpack dict into keyword args / collect extra keyword args / exponentf(**kwargs) · 2**10
:=Walrus — assign inside an expressionif (n := len(a)) > 5:
/True division7 / 23.5
//Floor division7 // 23
%Modulo7 % 21
@Decorator syntax / matrix multiplication (numpy)@staticmethod · A @ B
|Bitwise OR / set union / type union (3.10+)a | b · int | None
&Bitwise AND / set intersectiona & b
^Bitwise XOR / set symmetric differencea ^ b
~Bitwise NOT (inverts bits)~5-6
<< >>Bit shift left / right1 << 416
is / is notIdentity comparison (same object in memory)x is None
in / not inMembership test"a" in "cat"

28 Common Mistakes

python.gotchas — don't forget these