Configuration de l'Environnement et Prérequis
Pour interagir avec l'interpréteur Python, plusieurs commandes système sont essentielles. L'option --version ou -V affiche la version installée, tandis que -d active le mode débogage lors de l'analyse syntaxique.
Pour rendre un script exécutable sous les environnements Linux/Unix, il est nécessaire d'inclure un "shebang" en tête de fichier et de modifier les permissions d'exécution via chmod +x script.py.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Ceci est un commentaire sur une ligne
"""
Ceci est un commentaire
sur plusieurs lignes.
"""
L'encodage du fichier source peut être explicitement défini (bien que l'UTF-8 soit la norme depuis Python 3). Les mots réservés du langage, qui ne peuvent être utilisés comme identifiants, peuvent être listés dynamiquement via keyword.kwlist.
Architecture des Modules et Packages
Python organise le code en modules et packages pour structurer les espaces de noms.
- Importation : Il est possible d'importer un module entier (
import math), des fonctions spécifiques (from math import sqrt), ou d'utiliser des alias (import numpy as np). - Packages : Un répertoire est reconnu comme un package s'il contient un fichier
__init__.py. Ce fichier peut être vide ou contenir du code d'initialisation. - Contrôle des exports : La variable spéciale
__all__détermine quels sous-modules ou noms sont exportés lors de l'utilisation defrom package import *. - Exécution directe : Le bloc
if __name__ == '__main__':permet de définir un point d'entrée qui ne s'exécute que si le script est lancé directement, et non importé.
Système de Typage et Structures de Données
Python utilise un typage dynamique et fort. Les variables sont des références vers des objets en mémoire, créées lors de l'assignation. La fonction type() révèle la classe d'un objet, tandis que isinstance() vérifie l'appartenance à un type. L'instruction del supprime la référence à un objet.
Les structures de données se divisent en deux catégories : les immuables (dont la valeur ne peut être altérée après création) et les muables.
Données Immuables
- Numériques : Entiers (
int), flottants (float), booléens (bool) et nombres complexes (complex). Toute modification crée un nouvel objet en mémoire. - Chaînes de caractères (
str) : Séquences de caractères délimitées par des guillemets simples, doubles ou triples. Elles supportent le "slicing"[start:end:step], l'opérateur d'échappement\(ou les chaînes brutesr"..."), et la concaténation. Les indices commencent à 0 ou à -1 pour la fin. - Tuples (
tuple) : Séquences ordonnées définies par des parenthèses. Idéaux pour regrouper des données hétérogènes. Un tuple à un élément nécessite une virgule finale :(42,). - Octets (
bytes) : Séquences binaires immuables (valeurs de 0 à 255), cruciales pour le traitement de fichiers ou de protocoles réseau. Créés viab"data"oubytes().
Données Muables
- Listes (
list) : Tableaux dynamiques définis par des crochets[]. Elles peuvent contenir des types mixtes et leur taille peut être modifiée via le slicing ou des méthodes commeappend(). L'assignationa = bcrée un alias, pas une copie. - Dictionnaires (
dict) : Tables de hachage associant des clés immuables et uniques à des valeurs. Définis par des accolades{key: value}. Les méthodes.keys()et.values()permettent d'en extraire les composantes. - Ensembles (
set) : Collections non ordonnées d'éléments uniques, créées via{1, 2}ouset(). Ils excellent dans les opérations mathématiques : union (|), intersection (&), différence (-) et différence symétrique (^).
# Exemple d'utilisation des structures de données
coordinates = (48.8566, 2.3522) # Tuple
server_config = {"host": "10.0.0.1", "port": 8080} # Dictionnaire
active_nodes = ["node_A", "node_B", "node_C"] # Liste
admin_ips = {"192.168.1.10", "192.168.1.11"} # Ensemble
# Slicing de liste
backup_nodes = active_nodes[1:]
# Conversion explicite
node_tuple = tuple(active_nodes)
Opérateurs et Expressions
Python propose une riche variété d'opérateurs, évalués selon une priorité stricte (les parenthèses primant sur tout, suivies des opérations arithmétiques, puis des comparaisons, et enfin des opérateurs logiques).
- Arithmétiques :
+,-,*,/(division réelle),//(division entière),%(modulo),**(puissance). - Comparaison et Logique :
==,!=,<,>,<=,>=. Les opérateurs logiques sontand,or,not. Les comparaisons peuvent être chaînées :0 < x < 10. - Identité et Appartenance :
isetis notcomparent les adresses mémoire (id()).inetnot invérifient la présence dans une séquence. - Assignation : Outre les opérateurs classiques (
+=,-=), Python 3.8 a introduit l'opérateur morse:=, permettant d'assigner et d'évaluer une variable dans une même expression.
# Utilisation de l'opérateur morse (Walrus)
raw_payload = " system_telemetry_data "
if (clean_payload := raw_payload.strip()) and len(clean_payload) > 10:
print(f"Traitement de : {clean_payload}")
Programmation Fonctionnelle et Lambda
Les fonctions anonymes sont définies avec le mot-clé lambda. Elles sont souvent combinées avec des fonctions d'ordre supérieur :
map(): Applique une fonction à chaque élément d'un itérable.filter(): Conserve les éléments pour lesquels la fonction retourne True.sorted(): Trie un itérable, acceptant une fonctionkeypour définir le critère de tri.reduce()(modulefunctools) : Agrège une séquence en une seule valeur.
from functools import reduce
sensor_data = [12.4, 15.1, 8.9, 22.0, 14.5]
# Filtrer les valeurs supérieures à 10 et les multiplier par 2
processed = list(map(lambda x: x * 2, filter(lambda val: val > 10, sensor_data)))
# Calculer la somme totale
total = reduce(lambda acc, curr: acc + curr, processed, 0)
# Tri d'une liste de tuples basée sur le deuxième élément
metrics = [("cpu", 85), ("ram", 62), ("disk", 45)]
metrics_sorted = sorted(metrics, key=lambda m: m[1], reverse=True)
Structures de Contrôle
Conditions et Pattern Matching
Les brenchements conditionnels classiques utilisent if, elif, et else. Depuis Python 3.10, l'instruction match permet une analyse structurelle puissante, similaire au "switch" d'autres langages mais avec des capacités de déconstruction.
http_response = 403
match http_response:
case 200 | 201:
status = "Opération réussie"
case 400 | 401 | 403:
status = "Accès refusé ou requête invalide"
case code if code >= 500:
status = "Défaillance du serveur"
case _:
status = "Code non reconnu"
Boucles et Itérations
Les boucles for parcourent des itérables, tandis que while s'exécute tant qu'une condition est vraie. Les mots-clés break (sortie immédiate), continue (saut à l'itération suivante) et pass (opération nulle) contrôlent le flux.
Une particularité de Python est la clause else attachée aux boucles, qui s'exécute uniquement si la boucle s'est terminée normalement (sans rencontrer de break).
Plusieurs fonctions intégrées optimisent les itérations : range() pour les séquences numériques, enumerate() pour obtenir l'index et la valeur, zip() pour parcourir plusieurs séquences en parallèle, et reversed() pour l'ordre inverse.
tasks = ["initialisation", "connexion", "transfert"]
statuses = ["OK", "OK", "TIMEOUT"]
for index, (task, state) in enumerate(zip(tasks, statuses), start=1):
if state == "TIMEOUT":
print(f"Échec à l'étape {index} : {task}")
break
else:
print("Toutes les tâches ont été accomplies avec succès.")
Itérateurs et Générateurs
Le Protocole d'Itération
Un itérateur est un objet qui implémente les méthodes __iter__() (retournant l'objet lui-même) et __next__() (retournant la valeur suivante ou levant l'exception StopIteration). La boucle for gère ce protocole automatiquement.
class CustomRange:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
value = self.current
self.current += 1
return value
# Utilisation
for num in CustomRange(1, 4):
print(num)
Générateurs et Évaluation Paresseuse
Les générateurs offrent une syntaxe plus concise pour créer des itérateurs. En utilisant le mot-clé yield au lieu de return, la fonction sauvegarde son état d'exécution. Cela permet de produire des séquences de valeurs à la demande, optimisant ainsi l'utilisation de la mémoire pour les grands volumes de données.
def data_stream_simulator(max_packets):
packet_id = 0
while packet_id < max_packets:
# Simule un traitement coûteux ou une lecture I/O
yield {"id": packet_id, "status": "received"}
packet_id += 1
# Le générateur ne consomme pas de mémoire pour tous les paquets à la fois
stream = data_stream_simulator(5)
for packet in stream:
print(f"Traitement du paquet {packet['id']}")