Python __add__ et __iadd__ : copie ou mutation en place

Python __add__ et __iadd__ : copie ou mutation en place

__add__ et __iadd__ définissent deux comportements distincts pour l’addition en Python : l’un crée un nouvel objet, l’autre modifie l’existant. Cette distinction a des conséquences réelles sur les alias et les références partagées, et elle réserve des surprises même aux développeurs expérimentés. add : l’addition qui crée __add__ est appelée par l’opérateur +. Elle doit retourner un nouvel objet et laisser les opérandes inchangés. class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) a = Vector(1, 2) b = Vector(3, 4) c = a + b # nouvel objet Vector(4, 6) print(a.x, a.y) # 1 2 — a est inchangé print(id(a) == id(c)) # False — objets distincts a + b appelle a.__add__(b). Si __add__ n’est pas défini sur a ou retourne NotImplemented, Python essaie b.__radd__(a). ...

15 mai 2026 · 4 min · Anthony
Timing attacks en Django avec constant_time_compare

Timing attacks en Django avec constant_time_compare

Une comparaison == sur un token paraît anodine. En pratique, elle laisse filtrer une information mesurable : le temps d’exécution varie selon le nombre de caractères corrects. C’est le principe d’une timing attack, et c’est suffisant pour qu’un attaquant reconstitue le token caractère par caractère. Le problème : la comparaison qui s’arrête trop tôt Python compare les chaînes caractère par caractère et s’arrête dès qu’une différence est trouvée. def verify_token(request): user_token = request.GET.get('token') valid_token = "secret_abc123" if user_token == valid_token: return JsonResponse({'access': 'granted'}) return JsonResponse({'access': 'denied'}) Concrètement : ...

14 mai 2026 · 3 min · Anthony
Vues matérialisées vs cache Django pour les requêtes lentes

Vues matérialisées vs cache Django pour les requêtes lentes

Le réflexe face à un endpoint de reporting lent, c’est souvent le cache. Un @cache_page, un cache.set(), et le problème disparaît… jusqu’à la prochaine expiration. Cette approche a une limite structurelle que les vues matérialisées PostgreSQL résolvent à la racine. Le problème du cache sur les endpoints analytiques Le cache Django stocke le résultat d’une vue Python. La requête SQL coûteuse s’exécute quand même à chaque expiration du cache. Pour un rapport construit sur plusieurs JOINs et agrégations, ça signifie que le premier utilisateur après chaque cache miss attend plusieurs secondes. ...

13 mai 2026 · 4 min · Anthony
Python @property : de l'encapsulation aux descripteurs

Python @property : de l'encapsulation aux descripteurs

Accéder à r.width et écrire r.width = 15 avec la syntaxe d’un attribut normal, tout en exécutant de la validation ou du calcul derrière : c’est ce que @property apporte. Et quand cette logique doit se partager entre plusieurs classes, les descripteurs entrent en jeu. @property : getters et setters sans friction @property permet d’exposer un attribut calculé ou validé avec la même syntaxe qu’un attribut simple. class Rectangle: def __init__(self, width: float, height: float): self._width = width self._height = height @property def width(self) -> float: return self._width @width.setter def width(self, value: float) -> None: if value <= 0: raise ValueError("La largeur doit être positive.") self._width = value @property def area(self) -> float: return self._width * self._height L’avantage concret : l’API publique ne change pas. Ajouter de la validation sur un attribut existant ne casse aucun code appelant. @property sans setter crée un attribut en lecture seule. @nom.deleter gère la suppression via del. ...

12 mai 2026 · 3 min · Anthony
Connascence Python : les 9 types de couplage expliqués

Connascence Python : les 9 types de couplage expliqués

Le couplage est souvent traité comme une notion vague : “c’est trop couplé” ne dit rien sur ce qu’il faut changer. La connascence propose un vocabulaire précis pour nommer les différentes formes de couplage, les comparer, et décider lesquelles réduire en priorité. Le concept est documenté en détail sur connascence.io. Trois axes pour évaluer une connascence Chaque instance de connascence s’analyse selon trois axes : Force : plus une connascence est forte, plus elle est difficile à détecter et à refactoriser. Degré : une entité couplée à des centaines d’autres est plus problématique qu’une entité couplée à deux. Localité : deux composants proches (même classe, même module) peuvent se permettre des formes plus fortes. À distance, ces mêmes formes deviennent dangereuses. Les 9 types de connascence Connascence de nom (CoN) Plusieurs composants s’accordent sur le nom d’une entité. C’est la forme la plus faible et la plus inévitable. ...

11 mai 2026 · 4 min · Anthony
Optimiser les requêtes Django ORM avec defer(), only() et Prefetch()

Optimiser les requêtes Django ORM avec defer(), only() et Prefetch()

Par défaut, Django charge tous les champs d’un modèle à chaque requête. Sur une vue liste de 50 articles, cela signifie 50 fois le contenu complet, le résumé, les métadonnées, les champs de traduction, même si on n’affiche que le titre et la date. Quatre méthodes QuerySet Django permettent de contrôler précisément ce qui est chargé : defer(), only(), values_list() et Prefetch(). Résultat : 2 requêtes SQL au lieu de N+2, avec uniquement les colonnes nécessaires. ...

8 mai 2026 · 6 min · Anthony
Django squashmigrations : nettoyer l'historique des migrations

Django squashmigrations : nettoyer l'historique des migrations

Après quelques mois de développement, il n’est pas rare d’accumuler 30, 50, voire 100 fichiers de migration sur une application Django. Chaque lancement de test qui repart d’une base vide les rejoue toutes. Chaque déploiement sur un nouvel environnement aussi. squashmigrations permet de fusionner plusieurs migrations en une seule, sans perdre la compatibilité avec les environnements déjà déployés. La commande et ce qu’elle génère La syntaxe prend une plage de migrations : ...

7 mai 2026 · 5 min · Anthony
Django select_for_update() : verrouillage de lignes et concurrence

Django select_for_update() : verrouillage de lignes et concurrence

Deux requêtes simultanées lisent le stock d’un produit, constatent qu’il en reste un, et toutes les deux valident la commande. Le stock passe à -1. Ce type de condition de course est difficile à reproduire en développement et dévastateur en production. select_for_update() est la réponse de Django : poser un verrou SQL au moment de la lecture pour garantir qu’aucune autre transaction ne peut modifier la ligne avant la fin de l’opération. ...

6 mai 2026 · 4 min · Anthony
Python __slots__ : optimiser la mémoire des instances, concrètement

Python __slots__ : optimiser la mémoire des instances, concrètement

Python crée par défaut un dictionnaire __dict__ pour chaque instance de classe. C’est flexible, pratique, mais coûteux en mémoire quand on instancie des milliers ou des millions d’objets. __slots__ est le mécanisme qui supprime ce dictionnaire et stocke les attributs dans une structure compacte. Gain typique : 40 à 60 % de mémoire en moins par instance. Ce que fait Python sans slots Sans rien déclarer, chaque instance porte son propre __dict__ : ...

6 mai 2026 · 4 min · Anthony
Renommer les champs Django ORM avec F() dans values()

Renommer les champs Django ORM avec F() dans values()

Quand on expose des données depuis un modèle Django vers une API ou un serializer, les noms de champs du modèle ne correspondent pas toujours à ce qu’on veut retourner. Le réflexe habituel : récupérer les instances, puis renommer en Python. Il existe une meilleure option : laisser la base de données faire le travail via F() dans values(). Le problème : les noms de champs s’imposent class Task(models.Model): name = models.CharField(...) created_at = models.DateTimeField(...) Si on veut retourner nom_tache au lieu de name, on récupère les données puis on renomme en Python, soit via une compréhension de dict, soit dans le serializer. Dans les deux cas, la transformation se fait après coup, en mémoire. ...

5 mai 2026 · 3 min · Anthony

Newsletter

Reçois les nouveaux articles directement dans ta boite mail.

Pas de spam. Désabonnement en un clic.