Python Pro Guide
Python Pro Guide
MASTERY GUIDE
De débutant à développeur professionnel
def become_a_pro():
skills = load_all_chapters()
practice(skills, daily=True)
return 'Expert'
PYTHON MASTERY GUIDE [Link]
Programmation Orientée
04 Classes, héritage, dunder methods p.11
Objet
Programmation
07 asyncio, coroutines, event loop p.17
asynchrone
Performance &
09 Profiling, numpy, multiprocessing p.21
Optimisation
Projet professionnel
10 CLI app, API REST, best practices p.23
complet
CHAPITRE 01
01
1.1 Environnement de développement
Avant de coder, installe un environnement propre. Voici le workflow professionnel pour tout
nouveau projet Python.
Python est dynamiquement typé mais fortement typé : le type est déterminé à l'exécution, mais
les conversions implicites sont rares.
Mutabl
Type Exemple Description
e
Depuis Python 3.5+, les type hints permettent d'annoter le code. Elles n'affectent pas l'exécution
mais améliorent la lisibilité et permettent à mypy de détecter des bugs.
Comprendre la gestion mémoire de Python est essentiel pour écrire du code performant et éviter
les fuites.
y 0x2B3C
str: 'Hi' 0x2B3C
lst 0x3C4D
[1,2,3] 0x3C4D
fn 0x4D5E
1 import sys
2
3 # Taille en mémoire d'un objet
4 x = [1, 2, 3, 4, 5]
5 print([Link](x)) # 120 bytes
6
7 # Compteur de références
8 import ctypes
9 a = [1, 2, 3]
10 b = a # même objet, refcount += 1
11 print(id(a) == id(b)) # True
12
13 # Interning des petits entiers (-5 à 256)
14 x = 256; y = 256
15 print(x is y) # True (même objet)
16 x = 257; y = 257
17 print(x is y) # False (objets différents)
CHAPITRE 02
02
2.1 Listes — techniques avancées
1 # Dict comprehension
2 squares = {x: x**2 for x in range(10)}
3
4 # Merge de dicts (Python 3.9+)
5 d1 = {'a': 1, 'b': 2}
6 d2 = {'b': 3, 'c': 4}
7 merged = d1 | d2 # {'a':1, 'b':3, 'c':4}
8
9 # defaultdict — valeur par défaut automatique
10 from collections import defaultdict
11 word_count = defaultdict(int)
12 for word in [Link]():
13 word_count[word] += 1
14
15 # Counter — compter des éléments
16 from collections import Counter
17 c = Counter('abracadabra')
18 print(c.most_common(3)) # [('a',5),('b',2),('r',2)]
19
20 # OrderedDict (utile avant Python 3.7)
21 from collections import OrderedDict
22 od = OrderedDict([('un', 1), ('deux', 2)])
CHAPITRE 03
Fonctions avancées
Closures, décorateurs, fonctions d'ordre supérieur, générateurs, coroutines et annotations
de fonctions.
03
3.1 Closures & fonctions d'ordre supérieur
3.2 Décorateurs
Un décorateur est une fonction qui enveloppe une autre fonction pour modifier ou étendre son
comportement sans la modifier.
@retry(max=3)
@log_calls
@cache
def ma_fonction():
Python — Générateurs
CHAPITRE 04
04
4.1 Classes — anatomie complète
Animal
# Attributs
+nom: str
+age: int
# Methodes
__init__()
Chien parler() Chat
__str__()
# Attributs # Attributs
+race: str +couleur: str
# Methodes # Methodes
aboyer() miauler()
fetch() griffer()
1 class Dog(Animal):
2 def __init__(self, name: str, age: int, breed: str):
3 super().__init__(name, age) # appel parent
4 [Link] = breed
5
6 def speak(self) -> str:
7 return f'Woof! Je suis {[Link]}'
8
9 # MRO — Method Resolution Order
10 # print(Dog.__mro__)
11
12 # Héritage multiple & super()
13 class A:
14 def method(self): return 'A'
15
16 class B(A):
17 def method(self): return 'B > ' + super().method()
18
19 class C(A):
20 def method(self): return 'C > ' + super().method()
21
22 class D(B, C): # MRO: D -> B -> C -> A
23 pass
24
25 print(D().method()) # 'B > C > A'
Python — dataclasses
CHAPITRE 05
05
5.1 Exceptions — hiérarchie et bonnes pratiques
Python — Exceptions
1 # Exceptions personnalisées
2 class AppError(Exception):
3 """Erreur de base de l'application."""
4 def __init__(self, message: str, code: int = 0):
5 super().__init__(message)
6 [Link] = code
7
8 class ValidationError(AppError): pass
9 class DatabaseError(AppError): pass
10
11 # try / except / else / finally
12 def safe_divide(a: float, b: float) -> float:
13 try:
14 result = a / b
15 except ZeroDivisionError:
16 raise ValidationError('Diviseur ne peut pas être 0', 400)
17 except TypeError as e:
18 raise ValidationError(f'Type invalide: {e}', 422)
19 else:
20 return result # si aucune exception
21 finally:
22 pass # toujours exécuté
23
24 # ExceptionGroup (Python 3.11+)
25 try:
26 raise ExceptionGroup('multiple', [ValueError(), TypeError()])
27 except* ValueError as eg:
28 print(f'ValueError: {[Link]}')
CHAPITRE 06
06
6.1 Système d'import avancé
[Link]
CHAPITRE 07
Programmation Asynchrone
asyncio, coroutines, event loop, async/await, aiohttp, gestion des tâches et timeouts.
07
7.1 asyncio — fondamentaux
Event
Loop
Python — asyncio
1 import asyncio
2 from typing import AsyncIterator
3
4 # Coroutine simple
5 async def fetch_url(url: str) -> str:
6 await [Link](1) # I/O simulée
7 return f'Data from {url}'
8
9 # Lancer plusieurs tâches en parallèle
10 async def main():
11 urls = ['[Link] '[Link] '[Link]
12
13 # gather — toutes les tâches en parallèle
14 results = await [Link](*[fetch_url(u) for u in urls])
15
16 # TaskGroup (Python 3.11+) — annulation automatique
17 async with [Link]() as tg:
18 tasks = [tg.create_task(fetch_url(u)) for u in urls]
19 results2 = [[Link]() for t in tasks]
20
21 # Timeout
22 try:
23 async with [Link](5.0):
24 result = await fetch_url('[Link]
25 except TimeoutError:
26 print('Timeout!')
27
28 [Link](main())
1 # Générateur asynchrone
2 async def paginate(url: str) -> AsyncIterator[dict]:
3 page = 1
4 while True:
5 data = await fetch_page(url, page)
6 if not data: break
7 for item in data:
8 yield item
9 page += 1
10
11 async def process_all():
12 async for item in paginate('[Link]
13 await process(item)
14
15 # Context manager asynchrone
16 from contextlib import asynccontextmanager
17
18 @asynccontextmanager
19 async def db_transaction(conn):
20 await [Link]()
21 try:
22 yield conn
23 await [Link]()
24 except Exception:
25 await [Link]()
26 raise
27
28 # Semaphore — limiter la concurrence
29 sem = [Link](10) # max 10 requêtes simultanées
30
31 async def limited_fetch(url: str) -> str:
32 async with sem:
33 return await fetch_url(url)
CHAPITRE 08
08
8.1 pytest — framework de tests professionnel
1 # tests/test_models.py
2 import pytest
3 from [Link] import Mock, patch, AsyncMock
4
5 # Fixture — setup/teardown réutilisables
6 @[Link]
7 def sample_user() -> dict:
8 return {'id': 1, 'name': 'Alice', 'email': 'alice@[Link]'}
9
10 @[Link](scope='session')
11 def db_connection():
12 conn = create_connection(':memory:')
13 yield conn
14 [Link]()
15
16 # Parametrize — tester plusieurs cas
17 @[Link]('value,expected', [
18 (0, True), (42, False), (-1, False), (100, False),
19 ])
20 def test_is_zero(value, expected):
21 assert is_zero(value) == expected
22
23 # Test avec mock
24 def test_fetch_user(sample_user):
25 with patch('[Link]') as mock_get:
26 mock_get.return_value.json.return_value = sample_user
27 result = fetch_user(1)
28 assert result['name'] == 'Alice'
29 mock_get.assert_called_once()
30
31 # Test asynchrone
32 @[Link]
33 async def test_async_fetch():
34 result = await async_fetch('[Link]
35 assert result is not None
1 # [Link] ou [Link]
2 [[Link].ini_options]
3 testpaths = ['tests']
4 addopts = '-v --tb=short --cov=src --cov-report=html'
5 asyncio_mode = 'auto'
6
7 # Lancer les tests
8 pytest # tous les tests
9 pytest -k 'test_user' # filtrer par nom
10 pytest -x # arrêter au premier échec
11 pytest --lf # seulement les tests qui ont échoué
12 pytest -v --tb=long # verbose avec traceback complet
13
14 # Coverage
15 pytest --cov=src --cov-report=term-missing
16 # Objectif : > 90% de couverture
CHAPITRE 09
09
9.1 Profiling — identifier les goulots
Python — Profiling
list comprehension vs
2-5x plus rapide Construire des listes
boucle
10-100x plus
numpy arrays vs listes Calculs numériques
rapide
N x mémoire
generator vs list Grands datasets
économisée
Nx (N = nb de
multiprocessing CPU-bound tasks
CPU)
1 import numpy as np
2 from functools import lru_cache
3
4 # numpy — opérations vectorisées
5 a = [Link]([1, 2, 3, 4, 5], dtype=np.float64)
6 b = [Link](10**6)
7
8 # Opérations sur tout le tableau à la fois
9 result = [Link](a**2 + a**2) # vectorisé
10 matrix = [Link](1000, 1000)
11 eigenvalues = [Link](matrix)
12
13 # __slots__ — réduire l'empreinte mémoire
14 class Point:
15 __slots__ = ('x', 'y', 'z') # interdit __dict__
16
17 def __init__(self, x, y, z):
18 self.x, self.y, self.z = x, y, z
19
20 # multiprocessing — contourner le GIL
21 from multiprocessing import Pool
22
23 def cpu_intensive(n: int) -> int:
24 return sum(i**2 for i in range(n))
25
26 with Pool() as pool: # un processus par CPU
27 results = [Link](cpu_intensive, [10**6]*8)
CHAPITRE 10
10
10.1 Architecture du projet
1 # [Link]
2 from fastapi import FastAPI, Depends, HTTPException, status
3 from pydantic import BaseModel, EmailStr, Field
4 from typing import Annotated
5
6 app = FastAPI(title='Mon API', version='1.0.0')
7
8 # Schéma Pydantic — validation automatique
9 class UserCreate(BaseModel):
10 name: str = Field(min_length=2, max_length=50)
11 email: EmailStr
12 password: str = Field(min_length=8)
13
14 class UserResponse(BaseModel):
15 id: int
16 name: str
17 email: str
18 model_config = {'from_attributes': True}
19
20 # Dependency Injection
21 def get_db() -> Generator:
22 db = SessionLocal()
23 try: yield db
24 finally: [Link]()
25
26 DB = Annotated[Session, Depends(get_db)]
27
28 # Routes
29 @[Link]('/users', response_model=UserResponse,
30 status_code=status.HTTP_201_CREATED)
31 async def create_user(user: UserCreate, db: DB) -> UserResponse:
32 existing = [Link](User).filter([Link] == [Link]).first()
33 if existing:
34 raise HTTPException(status_code=400, detail='Email déjà utilisé')
35 db_user = User(**user.model_dump())
36 [Link](db_user)
37 [Link]()
38 return db_user
39
40 @[Link]('/users/{user_id}', response_model=UserResponse)
41 async def get_user(user_id: int, db: DB) -> UserResponse:
42 user = [Link](User, user_id)
43 if not user:
44 raise HTTPException(status_code=404, detail='Utilisateur non trouvé')
45 return user
FastAPI, Django,
Web Backend [Link]
SQLAlchemy
Machine
Scikit-learn, PyTorch, TF [Link]
Learning