Skip to Content
SnippetsPython

Python

Opérations sur les fichiers, pathlib, one-liners et bases SQLite pour le quotidien.

📁 Fichiers & pathlib

Lecture / écriture simple

import datetime # Lecture complĂšte — le contexte gĂšre la fermeture with open('data.txt') as f: contenu = f.read() # Écriture (Ă©crase) with open('output.txt', 'w') as f: f.write('ligne 1\nligne 2\n') # Écriture append avec horodatage with open('log.txt', 'a') as f: f.write(f'[{datetime.datetime.now():%Y-%m-%d %H:%M}] info\n')

Parcours de répertoire avec pathlib

from pathlib import Path # Tous les fichiers .py du projet, triés fichiers = sorted(Path('.').rglob('*.py')) # Taille totale d'un dossier (cohérent avec os.stat) taille = sum(p.stat().st_size for p in Path('docs').rglob('*') if p.is_file()) print(f'{taille / 1024:.1f} Ko') # Créer une arborescence (Parent / Enfant) racine = Path('/var/log') (justes := list(racine.glob('*.log')))[:3] # 3 premiers .log

Pitfall : Path.rglob('*') inclut les dossiers. Filtrer avec .is_file() pour ne garder que les fichiers.

Copie / déplacement / suppression

import shutil from pathlib import Path src = Path('source.txt') dst = Path('archive/source.txt') # Copie (bit à bit, préserve les métadonnées) shutil.copy2(src, dst) # Déplacement shutil.move('temp/', '/tmp/processed/') # Suppression récursive sûre (équivalent de `rm -rf`) if Path('trash').exists(): shutil.rmtree('trash')

🌍 Environnement & chemin

Variables d’environnement

import os # Lecture avec valeur par défaut (pas de KeyError) db_url = os.getenv('DATABASE_URL', 'sqlite:///local.db') # Lister les variables contenant un préfixe prefix = 'MYAPP_' config = {k: v for k, v in os.environ.items() if k.startswith(prefix)} # Définit la valeur si la clé n'existe pas encore os.environ.setdefault('LOG_LEVEL', 'INFO')

Chemins portables

from pathlib import Path # Chemin absolu résolu (symlinks suivis) dossier_projet = Path(__file__).resolve().parent.parent # Chemin relatif depuis un autre dossier relative = dossier_projet.relative_to(Path.home()) # PosixPath('projects/mon-app') # Extensions et suffixes p = Path('archive.tar.gz') p.stem # 'archive' p.suffix # '.gz' p.suffixes # ['.tar', '.gz'] p.with_suffix('.zip') # archive.tar.zip

Pitfall : os.path.join() fonctionne aussi, mais pathlib Ă©vite les problĂšmes de sĂ©parateurs sur Windows. PrivilĂ©gier pathlib quand c’est possible.

⚡ One-liners

List comprehensions & conditions

# pairs & odds nombres = list(range(20)) pairs = [x for x in nombres if x % 2 == 0] impairs = [x for x in nombres if x % 2 != 0] # Dictionnaire Ă  partir de deux listes clefs = ['nom', 'age', 'role'] valeurs = ['Alice', 30, 'dev'] dico = dict(zip(clefs, valeurs)) # {'nom': 'Alice', 'age': 30, 'role': 'dev'}

Dict unpacking & fusion

# Fusion de dicts — Python 3.9+ pref = {'port': 3000, 'host': 'localhost'} env = {'port': 8080, 'debug': True} config = {**pref, **env} # {'port': 8080, 'host': 'localhost', 'debug': True} # env Ă©crase pref sur les clĂ©s en conflit # Deep merge simple (2 niveaux max) def merge_deep(a, b): for k, v in b.items(): if k in a and isinstance(a[k], dict) and isinstance(v, dict): merge_deep(a[k], v) else: a[k] = v return a

Formatage de chaĂźnes

# f-string (Python 3.6+) prenom, age = 'Alice', 30 message = f'Bonjour {prenom}, tu as {age} ans' # Alignement / remplissage f'{42:>10}' # ' 42' f'{0.123:.2f}' # '0.12' f'{255:x}' # 'ff' (hex) f'{1024:b}' # '10000000000' (binaire) # string method alternatifs ' hello '.strip() # 'hello' 'HELLO'.casefold() # 'hello' ( NFC-safe ) 'ab-cd'.removeprefix('ab-') # 'cd' (3.9+) '.hello'.removesuffix('.hi') # 'hello' (3.9+)

đŸ—ƒïž SQLite — bases lĂ©gĂšres

Connexion & requĂȘtes simples

import sqlite3 db = sqlite3.connect('app.db') db.row_factory = sqlite3.Row # accĂ©der par nom de colonne # Une requĂȘte paramĂ©trĂ©e (Ă©vite le SQL injection) with db: db.execute( 'INSERT INTO users (nom, email) VALUES (?, ?)', ('Alice', 'alice@example.com') ) # Fetch for row in db.execute('SELECT nom, email FROM users'): print(f'{row["nom"]} <{row["email"]}>') # Comptage rapide compte = db.execute('SELECT COUNT(*) FROM users').fetchone()[0] print(f'{compte} utilisateur(s)')

RequĂȘtes avec paramĂštres

# ❌ Jamais faire — SQL injection risquĂ©e db.execute(f"SELECT * FROM users WHERE nom = '{nom}'") # ✅ Toujours faire — paramĂštres positionnels db.execute('SELECT * FROM users WHERE nom = ?', (nom,)) # ✅ ou noms explicites (Python 3.6+) db.execute('SELECT * FROM users WHERE nom = :nom', {'nom': nom})

Pitfall : sans db.row_factory = sqlite3.Row, les lignes ne sont accessibles que par index (row[0]), pas par nom de colonne. Oublier de définir row_factory rend le code fragile quand le schéma évolue.

🐛 Logging & dĂ©buggage rapide

Niveaux de log

import logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s [%(levelname)s] %(name)s: %(message)s', ) logger = logging.getLogger(__name__) logger.debug('Var intermĂ©diaire: %s', ma_var) logger.info('Point d\'entrĂ©e fonction X') logger.warning('Champ manquant: %s', champ) logger.error('Échec connexion DB: %s', exc)

Variables locales en débug

# afficher tout l'Ă©tat courant sans pprinter manuellement import sys def debug(): '''Imprime le frame d'appel actuel — Ă  appeler dans la fonction Ă  debugger.''' frame = sys._getframe(1) for nom, valeur in sorted(frame.f_locals.items()): print(f' {nom} = {valeur!r}')
# Usage : def traiter(donnees): for item in donnees: debug() # ⇐ envoie les vars locales au stderr resultat = calcul(item)