Python 3 — Cheatsheet
# wszystko co musisz wiedzieć · wersja PL
Co to jest Python?

Interpretowany, wysokopoziomowy język ogólnego przeznaczenia. Dynamicznie typowany, garbage-collected.

interpretowany dynamicznie typowany garbage collected multi-paradigm cross-platform
Paradygmaty
ParadygmatOpis
OOPklasy, dziedziczenie, enkapsulacja, polimorfizm
Proceduralnesekwencja instrukcji, funkcje
Funkcyjnelambda, map/filter/reduce, closures
Aspektowedekoratory
Mocne strony ✓
Czytelna, zwięzła składnia — szybka nauka
Ogromny ekosystem (PyPI: 500k+ paczek)
Dominuje w AI/ML (TensorFlow, PyTorch, sklearn)
Świetny do skryptowania, automatyzacji, prototypów
Batteries included — bogata stdlib
Aktywna społeczność, mnóstwo dokumentacji
Duck typing — elastyczność kodu
Słabe strony ✗
Wolny — GIL blokuje prawdziwy multithreading (CPU-bound)
Zużycie pamięci — obiekty są "ciężkie"
Słaby na mobile (nie ma dobrego runtime)
Dynamiczne typowanie = błędy w runtime zamiast compile-time
Nie do systemów real-time / embedded
Packaging/venv — piekło zależności
Indentacja jako składnia — irytuje przy copy-paste
Kluczowe zasady (The Zen of Python)

import this — 19 zasad projektowych Pythona

Beautiful is better than ugly
Explicit is better than implicit
Simple is better than complex
Readability counts
There should be one obvious way to do it
GIL — Global Interpreter Lock

Mutex w CPython który pozwala tylko jednemu wątkowi na raz wykonywać Python bytecode.

Problem: threads nie przyspieszają CPU-bound zadań
OK: I/O-bound (sieć, pliki) — GIL zwalniany podczas I/O
Rozwiązanie: multiprocessing lub async/await
# CPU-bound → multiprocessing
from multiprocessing import Pool
# I/O-bound → asyncio
import asyncio
Liczby
TypPrzykładUwagi
int42, -7, 0xFF, 0b101nieograniczona precyzja
float3.14, 1e-10, infIEEE 754 double
complex3+2jczęść rzeczywista + urojona
DecimalDecimal('0.1')dokładna arytmetyka
FractionFraction(1,3)ułamki
# operatory
7 // 2   # 3  — dzielenie całkowite
7 %  2   # 1  — modulo
2 ** 8   # 256 — potęgowanie
abs(-5)  # 5
round(3.567, 2)  # 3.57
String (str)

Niemutowalny ciąg znaków Unicode. Indeksowany od 0.

# tworzenie
s = 'hello'
s = "hello"
s = """wieloliniowy
string"""
s = r'\n nie escape'       # raw
s = f'wynik: {2+2}'     # f-string
s = b'bajty'               # bytes

# operacje
s[0]        # 'h'
s[-1]       # ostatni
s[1:3]      # slice 'el'
s[::-1]     # odwrócony
len(s)      # długość
s.upper()  s.lower()
s.strip()  s.split(',')
s.replace('a','b')
s.startswith('h')
','.join(['a','b'])  # 'a,b'
'sub' in s            # bool
Boolean i None
# bool (podklasa int!)
True  False
bool(0)    # False
bool('')   # False
bool([])   # False
bool(1)    # True

# Falsy: 0, '', [], {}, (), None, set()
# Truthy: wszystko inne

# None — brak wartości
x = None
x is None   # True (używaj 'is' nie ==)

# operatory logiczne
and  or  not
# short-circuit evaluation!
x = x or 'default'
Type hints (Python 3.5+)

Opcjonalne adnotacje typów — nie wymuszane w runtime, ale pomagają IDE i mypy.

def greet(name: str) -> str:
    return f'Cześć {name}'

x: int = 5
y: list[int] = [1, 2, 3]

from typing import Optional, Union
z: Optional[str] = None    # str | None
w: Union[int, str] = 5   # int | str (3.10+)
list — mutowalny, uporządkowany
a = [1, 2, 3]
a.append(4)        # [1,2,3,4]
a.extend([5,6])   # dodaj wiele
a.insert(0, 99)   # wstaw na indeks
a.pop()            # usuń ostatni
a.pop(0)          # usuń z indeksu
a.remove(2)       # usuń wartość
a.sort()           # in-place
sorted(a)          # nowa lista
a.reverse()
a[1:3] = [9,9]    # slice assignment

# list comprehension
sq = [x**2 for x in range(10) if x % 2 == 0]
tuple — niemutowalny, uporządkowany
t = (1, 2, 3)
t = 1, 2, 3     # bez nawiasów też działa
t = (1,)          # jednoelementowy — uwaga na ','

# unpacking
a, b, c = t
a, *rest = t       # star unpacking

# namedtuple
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
p.x  # 1

# tuple szybszy niż list, hashable → może być kluczem dict
dict — klucz:wartość, mutowalny (3.7+ ordered)
d = {'a': 1, 'b': 2}
d['c'] = 3
d.get('x', 0)    # default jeśli brak
d.keys()
d.values()
d.items()         # (k,v) pary
d.update({'d':4})
d.pop('a')
'a' in d           # sprawdź klucz

# merge (3.9+)
merged = d1 | d2
d1 |= d2

# dict comprehension
sq = {k: v**2 for k,v in d.items()}

# defaultdict
from collections import defaultdict
dd = defaultdict(list)
set — unikalny, nieuporządkowany
s = {1, 2, 3}
s = set([1,2,2,3])  # {1,2,3}
s.add(4)
s.discard(2)       # bez błędu jeśli brak
s.remove(2)        # KeyError jeśli brak

# operacje zbiorowe
a | b   # suma (union)
a & b   # iloczyn (intersection)
a - b   # różnica
a ^ b   # różnica symetryczna
a <= b  # podzbiór

# frozenset — niemutowalny, hashable
fs = frozenset({1,2,3})
Przydatne z collections
from collections import (
    Counter, deque, OrderedDict,
    defaultdict, ChainMap
)

# Counter — zliczanie
c = Counter('abracadabra')
c.most_common(3)

# deque — kolejka O(1) append/pop obu stron
dq = deque(maxlen=100)
dq.appendleft(0)
dq.rotate(1)

# ChainMap — wiele dict jako jeden
cm = ChainMap(d1, d2)
Definicja funkcji
def add(a: int, b: int = 0) -> int:
    """Docstring — opis funkcji."""
    return a + b

# *args — dowolna liczba pozycyjnych
def suma(*args):
    return sum(args)

# **kwargs — dowolna liczba nazwanych
def info(**kwargs):
    for k, v in kwargs.items():
        print(f'{k}: {v}')

# keyword-only (po *)
def f(a, *, b, c=1): pass

# positional-only (przed /)
def g(a, b, /, c): pass
Lambda i funkcje wyższe
# lambda — anonimowa, jednolinijkowa
sq = lambda x: x ** 2
sq(5)  # 25

# map, filter, reduce
list(map(lambda x: x*2, [1,2,3]))
list(filter(lambda x: x>2, [1,2,3]))

from functools import reduce
reduce(lambda a,b: a+b, [1,2,3])

# sorted z kluczem
sorted(items, key=lambda x: x.age)

# partial
from functools import partial
double = partial(mul, 2)
Dekoratory
# dekorator — funkcja opakowująca funkcję
def moj_dekorator(func):
    def wrapper(*args, **kwargs):
        print('przed')
        wynik = func(*args, **kwargs)
        print('po')
        return wynik
    return wrapper

@moj_dekorator
def hello(): print('hello')

# wbudowane dekoratory
@staticmethod    # bez self
@classmethod     # cls zamiast self
@property        # getter jak atrybut

# functools.wraps — zachowuje metadane
from functools import wraps, lru_cache

@lru_cache(maxsize=128)   # memoizacja!
def fib(n): return n if n<2 else fib(n-1)+fib(n-2)
Generatory

Leniwe sekwencje — nie ładują wszystkiego do pamięci naraz.

# generator function (yield)
def squares(n):
    for i in range(n):
        yield i ** 2

for sq in squares(5):
    print(sq)

# generator expression (jak comprehension)
gen = (x**2 for x in range(1000000))
next(gen)   # jeden na raz

# yield from — deleguj do pod-generatora
def flatten(lst):
    for item in lst:
        if isinstance(item, list):
            yield from flatten(item)
        else: yield item
Closures i scope (LEGB)

Python szuka nazw w kolejności: Local → Enclosing → Global → Built-in

# closure
def counter(start=0):
    count = [start]
    def inc():
        count[0] += 1
        return count[0]
    return inc

# nonlocal — modyfikuj zmienną z enclosing
def outer():
    x = 10
    def inner():
        nonlocal x
        x += 1
    inner()

# global — modyfikuj zmienną globalną
g = 0
def f():
    global g; g += 1
Klasa — pełny przykład
class Animal:
    # atrybut klasy (współdzielony)
    kingdom = 'Animalia'
    
    def __init__(self, name: str, age: int):
        self.name = name          # atrybut instancji
        self._age = age           # _ = konwencja "prywatny"
        self.__secret = 'X'      # __ = name mangling

    def speak(self) -> str:       # metoda instancji
        return f'I am {self.name}'

    @property
    def age(self): return self._age

    @age.setter
    def age(self, v):
        if v < 0: raise ValueError
        self._age = v

    @classmethod
    def create(cls, name): return cls(name, 0)

    @staticmethod
    def is_animal(obj): return isinstance(obj, Animal)

    def __repr__(self): return f'Animal({self.name!r})'
    def __str__(self):  return self.name
    def __eq__(self, o): return self.name == o.name
    def __len__(self): return self._age

class Dog(Animal):                 # dziedziczenie
    def speak(self): return 'Woof!'  # override
    def fetch(self):
        super().speak()              # wywołaj rodzica
Dunder metody (Magic Methods)
MetodaKiedy wywoływana
__init__konstruktor (tworzenie obiektu)
__repr__repr(obj) — developerski opis
__str__str(obj), print(obj)
__len__len(obj)
__getitem__obj[key]
__setitem__obj[key] = val
__contains__x in obj
__iter__for x in obj
__call__obj()
__enter__/__exit__with obj:
__add__/__mul__obj + other
__eq__/__lt__==, <
__hash__hash(obj), dict key
dataclass i ABC
from dataclasses import dataclass, field

@dataclass
class Point:
    x: float
    y: float
    z: float = 0.0
    tags: list = field(default_factory=list)
# auto: __init__, __repr__, __eq__

@dataclass(frozen=True)  # niemutowalny
class Frozen: x: int

# Klasa abstrakcyjna
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self) -> float: ...

class Circle(Shape):
    def __init__(self, r): self.r = r
    def area(self): return 3.14 * self.r**2
Warunki i pętle
# if / elif / else
if x > 0:    ...
elif x == 0: ...
else:        ...

# ternary
val = 'tak' if x > 0 else 'nie'

# match/case (3.10+)
match command:
    case 'quit':  ...
    case 'go', direction: ...
    case _: ...  # wildcard

# for
for i in range(10): ...
for i, v in enumerate(lst): ...
for a, b in zip(l1, l2): ...
else: ...  # wykonuje się jeśli brak break

# while
while condition:
    if bad: break
    if skip: continue
Wyjątki
try:
    risky()
except ValueError as e:
    print(e)
except (TypeError, KeyError):
    print('kilka typów')
except Exception:        # łapie prawie wszystko
    raise                 # ponownie rzuć
else:                     # jeśli NIE było wyjątku
    ok()
finally:                  # zawsze
    cleanup()

# własny wyjątek
class AppError(Exception):
    def __init__(self, msg, code):
        super().__init__(msg)
        self.code = code

raise AppError('błąd', 404)
Context Managers
# with — auto cleanup
with open('plik.txt', 'r', encoding='utf-8') as f:
    data = f.read()

# własny context manager
class Timer:
    def __enter__(self):
        self.start = time.time()
        return self
    def __exit__(self, *args):
        print(time.time() - self.start)

# lub dekoratorem
from contextlib import contextmanager

@contextmanager
def managed():
    setup()
    yield
    cleanup()
Async / Await
import asyncio

async def fetch(url):
    await asyncio.sleep(1)   # non-blocking
    return 'data'

async def main():
    # równolegle
    r1, r2 = await asyncio.gather(
        fetch('url1'),
        fetch('url2')
    )

asyncio.run(main())

# async generator
async def stream():
    for i in range(5):
        await asyncio.sleep(0.1)
        yield i
Wbudowane funkcje
FunkcjaCo robi
len(x)długość
range(n)sekwencja liczb
enumerate(it)indeks + wartość
zip(a, b)pary elementów
map(f, it)zastosuj funkcję
filter(f, it)filtruj
sorted(it)posortowana kopia
reversed(it)odwrócony iterator
any(it) / all(it)bool na kolekcji
min/max/sumagregaty
isinstance(o, T)sprawdź typ
hasattr/getattr/setattratrybuty obiektu
dir(obj)lista atrybutów
vars(obj)__dict__ obiektu
id(obj)adres w pamięci
hash(obj)hash value
open()plik
input()wejście od użytkownika
Stdlib — kluczowe moduły
ModułDo czego
os / pathlibsystem plików
sysinterpreter, argv
jsonJSON encode/decode
rewyrażenia regularne
datetimedaty i czas
math / statisticsobliczenia
randomlosowość
itertoolskombinatoryka iteratorów
functoolsHOF, caching, partial
threadingwątki (I/O-bound)
multiprocessingprocesy (CPU-bound)
asyncioasync I/O
subprocessuruchom proces zewnętrzny
logginglogi
unittest / pytesttesty
typingtype hints
dataclassesklasy danych
enumenumeracje
abcklasy abstrakcyjne
Konwersje typów
int('42')       # str → int
int('FF', 16)   # hex → int
float('3.14')   # str → float
str(42)         # → str
bool(0)         # → False
list({1,2})     # set → list
tuple([1,2])   # list → tuple
set([1,1,2])   # list → set (usuwa duplikaty)
dict([('a',1)]) # list par → dict
chr(65)         # 'A'
ord('A')        # 65
hex(255)        # '0xff'
bin(10)         # '0b1010'
Protokoły / Duck typing

"If it walks like a duck..." — Python sprawdza metody, nie typy.

# Iterable: __iter__
# Iterator: __iter__ + __next__
# Sequence: __getitem__ + __len__
# Mapping: __getitem__ + __len__ + __iter__
# Callable: __call__
# Context Manager: __enter__ + __exit__

# typing.Protocol (3.8+)
from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...
Comprehensions — wszystkie typy
# list comprehension
[x**2 for x in range(10)]

# dict comprehension
{k: v for k, v in d.items() if v}

# set comprehension
{x % 3 for x in range(10)}

# generator expression (leniwy)
(line.strip() for line in file)

# zagnieżdżone
flat = [x for row in matrix for x in row]

# walrus operator (3.8+)
if (n := len(data)) > 100:
    print(f'długi: {n}')

filtered = [y := f(x), y**2]
Moduły i pakiety
# importy
import os
import os.path as osp
from pathlib import Path
from . import modul        # relatywny
from .. import coś         # poziom wyżej

# __name__
if __name__ == '__main__':
    main()

# __all__ — eksportuj z modułu
__all__ = ['MyClass', 'my_func']

# struktura pakietu
# mypackage/
#   __init__.py
#   module.py
#   subpkg/__init__.py
Zarządzanie środowiskiem
# venv
python3 -m venv .venv
source .venv/bin/activate  # Linux/Mac
.venv\Scripts\activate     # Windows

# pip
pip install requests
pip freeze > requirements.txt
pip install -r requirements.txt

# pyproject.toml (nowoczesne)
# [project]
# name = "myapp"
# dependencies = ["requests"]

# Popularne narzędzia:
# uv       — szybszy pip/venv
# poetry   — zarządzanie zależnościami
# pyenv    — wiele wersji Python
# ruff     — szybki linter/formatter
# mypy     — statyczne typowanie
Metaklasy i __slots__
# __slots__ — oszczędność pamięci
class Point:
    __slots__ = ['x', 'y']  # brak __dict__!
    def __init__(self, x, y):
        self.x = x; self.y = y

# Metaklasa — klasa klas
class Meta(type):
    def __new__(mcs, name, bases, ns):
        return super().__new__(mcs, name, bases, ns)

class MyClass(metaclass=Meta): pass

# Descriptor protocol
class Validator:
    def __get__(self, obj, t): ...
    def __set__(self, obj, val): ...
    def __delete__(self, obj): ...
Najważniejsze wzorce
# Singleton
class Singleton:
    _inst = None
    def __new__(cls):
        if not cls._inst:
            cls._inst = super().__new__(cls)
        return cls._inst

# Dependency Injection
def process(data, logger=None):
    logger = logger or print
    logger('processing')

# Registry
_registry = {}
def register(name):
    def dec(cls):
        _registry[name] = cls
        return cls
    return dec