- Manipulation du temps avec time et datetime
La gestion des dates et des horaires est cruciale dans de nombreuses applications. Le module time permet de travailler avec des horodatages (timestamps), tandis que datetime offre une approche orientée objet pour l'arithmétique temporelle.
import time
from datetime import datetime, timedelta
# Conversion d'un horodatage en chaîne formatée
current_timestamp = time.time()
structured_time = time.localtime(current_timestamp)
formatted_date = time.strftime("%d/%m/%Y %H:%M:%S", structured_time)
print(f"Date formatée : {formatted_date}")
# Arithmétique temporelle avec datetime
now = datetime.now()
future_date = now + timedelta(days=5, hours=12, minutes=30)
past_date = now - timedelta(days=3)
print(f"Dans 5 jours et 12 heures : {future_date.strftime('%Y-%m-%d %H:%M')}")
print(f"Il y a 3 jours : {past_date.strftime('%Y-%m-%d')}")
# Modification d'un composant temporel spécifique
custom_time = now.replace(hour=8, minute=0, second=0)
print(f"Heure modifiée : {custom_time.strftime('%H:%M:%S')}")
- Génération d'aléatoire avec random
Le module random fournit des générateurs de nombres pseudo-aléatoires. Il est couramment utilisé pour les simulations, les tirages au sort ou la génération de tokens de sécurité simples.
import random
import string
# Génération de nombres flottants et entiers
print(f"Flottant [0.0, 1.0) : {random.random()}")
print(f"Entier [1, 10] : {random.randint(1, 10)}")
# Sélection et mélange de collections
data_pool = ['alpha', 'beta', 'gamma', 'delta']
print(f"Élément aléatoire : {random.choice(data_pool)}")
print(f"Échantillon de 2 éléments : {random.sample(data_pool, 2)}")
random.shuffle(data_pool)
print(f"Collection mélangée : {data_pool}")
# Fonction utilitaire pour générer un token alphanumérique
def generate_secure_token(length=12):
characters = string.ascii_uppercase + string.digits
return "".join(random.choices(characters, k=length))
print(f"Token généré : {generate_secure_token()}")
- Interactions Système avec os
Le module os offre une interface portable pour interagir avec le système d'exploitation. Il est indispensable pour la manipulation de chemins, la gestion des répertoires et l'accès aux variables d'environnement.
import os
# Gestion des chemins
base_dir = os.path.abspath(os.curdir)
target_path = os.path.join(base_dir, "data", "exports")
# Création de répertoires récursifs
if not os.path.exists(target_path):
os.makedirs(target_path)
print(f"Répertoire créé : {target_path}")
# Informations sur l'environnement
print(f"Séparateur de chemin : {os.sep}")
print(f"Plateforme : {os.name}")
print(f"Utilisateur courant : {os.environ.get('USER', 'Inconnu')}")
# Nettoyage
if os.path.exists(target_path):
os.rmdir(target_path)
os.rmdir(os.path.join(base_dir, "data"))
- Paramètres Système avec sys
Le module sys donne accès aux variables et fonctions qui interagissent fortement avec l'interpréteur Python.
import sys
print(f"Version de l'interpréteur : {sys.version.split()[0]}")
print(f"Plateforme d'exécution : {sys.platform}")
print(f"Valeur maximale d'un entier : {sys.maxsize}")
# Gestion des arguments de ligne de commande
if len(sys.argv) > 1:
print(f"Premier argument passé au script : {sys.argv[1]}")
else:
print("Aucun argument fourni lors de l'exécution.")
- Opérations avancées sur les fichiers avec shutil et tarfile
Pour des opérations de haut niveau comme la copei d'arborescences, le déplacement ou la compression de fichiers, shutil est l'outil de prédilection. Il peut être combiné avec tarfile pour l'extraction.
import shutil
import os
source_dir = "app_data"
backup_dir = "app_backup"
# Préparation des données de test
os.makedirs(source_dir, exist_ok=True)
with open(os.path.join(source_dir, "config.txt"), "w") as f:
f.write("param=true")
# Copie récursive avec exclusion de certains fichiers
if os.path.exists(source_dir):
shutil.copytree(
source_dir,
backup_dir,
ignore=shutil.ignore_patterns("*.tmp", "*.log"),
dirs_exist_ok=True
)
# Création d'une archive compressée
archive_name = shutil.make_archive("data_backup", "gztar", backup_dir)
print(f"Archive créée avec succès : {archive_name}")
# Nettoyage des répertoires de test
shutil.rmtree(source_dir)
shutil.rmtree(backup_dir)
- Sérialisation de données avec json et pickle
La sérialisation consiste à convertir des structures de données en mémoire en un format stocakble ou transmissible. json est universel et interopérable, tandis que pickle est spécifique à Python mais supporte des objets complexes.
import json
import pickle
user_profile = {"id": 42, "username": "dev_sys", "active": True, "roles": ["admin", "editor"]}
# Sérialisation JSON (Interopérabilité)
json_string = json.dumps(user_profile, indent=4)
with open("profile.json", "w", encoding="utf-8") as f:
json.dump(user_profile, f)
# Sérialisation Pickle (Objets Python natifs)
with open("profile.pkl", "wb") as f:
pickle.dump(user_profile, f)
# Désérialisation
with open("profile.pkl", "rb") as f:
restored_profile = pickle.load(f)
print(f"Profil restauré via Pickle : {restored_profile['username']}")
- Stockage persistant simple avec shelve
Le module shelve implémente un dictionnaire persistant. Les clés doivent être des chaînes de caractères, mais les valeurs peuvent être n'importe quel objet Python sérialisable.
import shelve
import os
db_file = "app_state"
# Écriture de données
with shelve.open(db_file) as db:
db["user_preferences"] = {"theme": "dark", "notifications": False}
db["last_login"] = "2023-10-25T14:30:00"
# Lecture de données
with shelve.open(db_file) as db:
if "user_preferences" in db:
theme = db["user_preferences"]["theme"]
print(f"Thème utilisateur chargé : {theme}")
# Suppression du fichier de test généré
for ext in [".db", ".dir", ".bak", ".dat"]:
if os.path.exists(db_file + ext):
os.remove(db_file + ext)
- Échange de données avec xml
Bien que JSON soit aujourd'hui omniprésent, XML reste un standard dans de nombreux systèmes legacy et services financiers. Le module xml.etree.ElementTree permet de parser et créer des documents XML.
import xml.etree.ElementTree as ET
xml_data = """
<configuration>
<database host="192.168.1.50" port="5432">
<user>db_admin</user>
</database>
</configuration>
"""
# Parsing de la chaîne XML
root = ET.fromstring(xml_data)
db_node = root.find("database")
if db_node is not None:
host = db_node.get("host")
user = db_node.find("user").text
print(f"Connexion à la base : {user}@{host}")
- Fichiers de configuration avec configparser
Pour lire et écrire des fichiers de configuration au format INI, configparser est l'outil standard. Il gère les sections, les clés et le typage de base.
import configparser
import os
config_file = "settings.ini"
config = configparser.ConfigParser()
# Création et écriture d'une configuration
config["SERVER"] = {"host": "127.0.0.1", "port": "8080"}
config["DATABASE"] = {"engine": "postgresql", "timeout": "30"}
with open(config_file, "w") as f:
config.write(f)
# Lecture et typage
config.read(config_file)
server_port = config.getint("SERVER", "port")
db_timeout = config.getfloat("DATABASE", "timeout")
print(f"Le serveur écoute sur le port : {server_port}")
print(f"Timeout de la base de données : {db_timeout}s")
# Modification et nettoyage
config.remove_option("DATABASE", "timeout")
os.remove(config_file)
- Empreintes cryptographiques avec hashlib
Le module hashlib fournit des algorithmes de hachage sécurisés (SHA-256, SHA-512, etc.). Ces fonctions sont unidirectionnelles et essentielles pour vérifier l'intégrité des données ou stocker des mots de passe.
import hashlib
def generate_hash(data: str, salt: str = "s3cr3t") -> str:
hasher = hashlib.sha256()
# Combinaison des données et du salt avant hachage
hasher.update((data + salt).encode("utf-8"))
return hasher.hexdigest()
password = "MonMotDePasseComplexe!"
secure_hash = generate_hash(password)
print(f"Empreinte SHA-256 : {secure_hash}")
print(f"Longueur de l'empreinte : {len(secure_hash)} caractères")
- Exécution de sous-processus avec subprocess
subprocess remplace les anciens modules comme os.system. Il permet de lancer de nouvelles applications, de se connecter à leurs flux d'entrée/sortie et d'obtenir leurs codes de retour.
import subprocess
def get_python_version():
try:
# Exécution sécurisée sans passer par le shell
result = subprocess.run(
["python", "--version"],
capture_output=True,
text=True,
check=True
)
return result.stdout.strip()
except FileNotFoundError:
return "Python n'est pas installé ou n'est pas dans le PATH."
except subprocess.CalledProcessError as e:
return f"Erreur d'exécution : {e.stderr}"
print(f"Information système : {get_python_version()}")
- Journalisation d'événements avec logging
Pour le suivi et le débogage des applications, le module logging offre un système flexible. Il permet de diriger les messages vers la console, des fichiers ou des services externes, avec différents niveaux de gravité.
import logging.config
import os
LOGGING_CONFIG = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"detailed": {
"format": "%(asctime)s | %(levelname)-8s | %(module)s:%(lineno)d | %(message)s",
"datefmt": "%Y-%m-%d %H:%M:%S"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "detailed"
},
"file": {
"class": "logging.FileHandler",
"filename": "application.log",
"level": "INFO",
"formatter": "detailed",
"encoding": "utf-8"
}
},
"root": {
"handlers": ["console", "file"],
"level": "DEBUG"
}
}
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("mon_application")
logger.debug("Initialisation des paramètres de configuration.")
logger.info("Démarrage du service principal.")
logger.warning("Utilisation de la mémoire supérieure à 80%.")
logger.error("Échec de la connexion à la base de données.")
# Nettoyage du fichier de log généré
if os.path.exists("application.log"):
os.remove("application.log")