Démarré en 2001 par Fernando Perez, le projet IPython visait à créer un environnement Python interactif plus puissant. Il a évolué pour devenir bien plus qu'une simple amélioration du shell Python standard. IPython offre une console graphique pour le traçage, un environnement de calcul interactif basé sur le web (le précurseur de Jupyter Notebook), et un moteur léger pour le calcul parallèle rapide.
En tant qu'outil de ligne de commande Python interactif modernisé, ipython remplace l'invite standard de Python par des indications In et Out distinctes, signalant clairement les entrées de commande et les résultats d'exécution.
Installation d'IPython
Installation dans un environnement Python existant
Si Python est déjà installé sur votre système, vous pouvez installer IPython via pip :
pip install ipython
Une fois l'installation terminée, un message de succès s'affichera. Vous pouvez ensuite lancer IPython en tapant ipython dans votre terminal.
L'interface d'IPython se distingue par ses invites In [n]: pour l'entrée et Out[n]: pour la sortie des commandes, où n est un numéro de séquence.
Fonctionnalités Clés d'IPython
Autocomplétion via la touche Tab
IPython améliore considérablement la productivité grâce à son autocomplétion intelligente. En tapant une partie d'un nom de variable, de fonction ou de module, puis en appuyant sur la touche Tab, IPython propose des complétions possibles.
Exécution de Comandes Système
IPython permet d'exécuter directement des commandes du système d'exploitation. Certaines commandes courantes sont même prises en charge nativement sans préfixe, tandis que d'autres nécessitent le préfixe !.
Commandes système intégrées
In [1]: pwd # Affiche le répertoire de travail actuel
Out[1]: '/home/utilisateur'
In [2]: cd .. # Remonte d'un répertoire
/
Exécution de commandes shell avec '!'
Pour exécuter n'importe quelle commande shell, il suffit de la préfixer avec un point d'exclamation ! :
In [3]: !ls -lha
total 48K
drwxr-xr-x 5 utilisateur groupe 4,0K déc 14 10:30 .
drwxr-xr-x 19 root root 4,0K déc 13 16:20 ..
-rw-r--r-- 1 utilisateur groupe 12K jan 20 2023 mon_script.py
... (autres fichiers et répertoires)
In [4]: output = !echo "Bonjour depuis IPython"
In [5]: print(output)
['Bonjour depuis IPython']
Introspection d'Objets avec '?'
Le mécanisme d'introspection d'IPython, accessible en ajoutant un point d'interrogation ? avant ou après un nom de variable, fonction ou module, fournit des informations détaillées sur l'objet, telles que son type, sa docstring et sa signature.
In [1]: ma_chaine = "Exemple de texte"
In [2]: ma_chaine.upper?
Type: builtin_function_or_method
String form: <built-in at="" method="" object="" of="" str="" upper="">
Docstring: S.upper() -> str
Return a copy of S converted to uppercase.
</built-in>
L'utilisation de deux points d'interrogation ?? tente d'afficher le code source de l'objet, si celui-ci est disponible.
Raccourcis Clavier Essentiels
IPython intègre une série de raccourcis clavier pour naviguer et manipuler le texte dans la console :
Ctrl-PouFlèche Haut: Recherche les commandes précédentes dans l'historique.Ctrl-NouFlèche Bas: Recherche les commandes suivantes dans l'historique.Ctrl-R: Recherche inversée incrémentale dans l'historique des commandes.Ctrl-Shift-V: Colle le texte du presse-papiers.Ctrl-C: Interrompt l'exécution de la commande en cours.Ctrl-A: Déplace le curseur au début de la ligne.Ctrl-E: Déplace le curseur à la fin de la ligne.Ctrl-K: Supprime le texte depuis le curseur jusqu'à la fin de la ligne.Ctrl-U: Efface tout le texte sur la ligne actuelle.Ctrl-F: Déplace le curseur d'un caractère vers l'avant.Ctrl-B: Déplace le curseur d'un caractère vers l'arrière.Ctrl-L: Efface l'écran de la console.
Commandes Magiques (Magic Commands)
Les commandes magiques d'IPython, préfixées par un %, étendent les capacités du shell en permettant des opérations spécifiques non disponibles directement en Python. Une commande magique à double pourcentage %% s'applique à toute une cellule de code.
Voici quelques commandes magiques courantes :
%quickref: Affiche une référence rapide d'IPython.%magic: Affiche la documentation détaillée de toutes les commandes magiques.%debug: Démarre le débogueur interactif après la dernière exception.%hist: Affiche l'historique des commandes (entrées et sorties).%paste: Exécute le code Python contenu dans le presse-papiers.%reset: Supprime toutes les variables/noms de l'espace de noms interactif.%run script.py: Exécute un script Python dans IPython.%time statement: Mesure le temps d'exécution d'une instruction.%timeit statement: Exécute une instruction plusieurs fois pour une mesure précise du temps moyen.%whos: Liste les variables définies dans l'espace de noms, avec leur type.%xdel variable: Supprime une variable et tente de libérer toutes les références à son objet.
Pour explorer les commandes magiques, utilisez %magic ou %cmd? pour la documentation spécifique d'une commande.
Mesure du temps d'exécution : %time et %timeit
Ces commandes sont cruciales pour profiler de petites sections de codee :
In [1]: def calculer_carres(n):
...: return [x*x for x in range(n)]
...:
In [2]: %time resultat = calculer_carres(10000)
CPU times: user 1.34 ms, sys: 12 µs, total: 1.35 ms
Wall time: 1.35 ms
In [3]: %timeit resultat = calculer_carres(10000)
1.25 ms ± 15.6 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Système de marque-pages de répertoires
IPython permet de créer des alias pour des chemins de répertoires, simplifiant la navigation :
In [4]: %bookmark mon_projet /chemin/vers/mon/projet
In [5]: %bookmark config_app /etc/application/config
In [6]: %bookmark -l # Liste tous les marque-pages
Current bookmarks:
config_app -> /etc/application/config
mon_projet -> /chemin/vers/mon/projet
In [7]: pwd
Out[7]: '/'
In [8]: cd mon_projet
(bookmark:mon_projet) -> /chemin/vers/mon/projet
/chemin/vers/mon/projet
In [9]: cd config_app
(bookmark:config_app) -> /etc/application/config
/etc/application/config
Journalisation de l'historique
La commande %logstart permet d'enregistrer toutes les entrées et sorties de la session IPython dans un fichier. D'autres commandes comme %logoff, %logon, %logstate et %logstop gèrent ce processus.
Interaction avec le système d'exploitation
IPython fournit plusieurs commandes magiques pour interagir avec l'environnement système :
| Commande | Description |
|---|---|
!cmd |
Exécute cmd dans le shell système. |
output=!cmd args |
Exécute cmd et stocke la sortie standard dans output. |
%alias alias_name cmd |
Définit un alias pour une commande shell. |
%bookmark |
Utilise le système de marque-pages de répertoires d'IPython. |
%cd directory |
Change le répertoire de travail actuel. |
%pwd |
Affiche le répertoire de travail actuel. |
%pushd directory |
Pousse le répertoire actuel sur une pile et se déplace vers directory. |
%popd |
Fait sortir le répertoire du haut de la pile et s'y déplace. |
%dirs |
Affiche la pile des répertoires. |
%dhist |
Affiche l'historique des changements de répertoire. |
%env |
Affiche les variables d'environnement système sous forme de dictionnaire. |
IPython Notebook (Jupyter)
Le projet IPython Notebook est le prédécesseur direct de Jupyter Notebook. Pour utiliser cette interface web interactive, vous devez installer Jupyter :
pip install jupyter
Après l'installation, lancez jupyter notebook pour ouvrir l'interface dans votre navigateur.
Utilisation Avancée d'IPython
Alias Personnalisés
Vous pouvez définir des alias pour des commandes shell complexes, y compris celles avec des paramètres :
In [1]: %alias afficher_details ls -lha | grep %s
In [2]: afficher_details .txt
-rw-r--r-- 1 utilisateur groupe 12K jan 20 2023 fichier_log.txt
-rw-r--r-- 1 utilisateur groupe 8K fév 15 2023 rapport.txt
Pour que les alias soient persistants au-delà de la session actuelle, utilisez la commande %store :
In [3]: %store afficher_details
Alias stored: afficher_details (ls -lha | grep %s)
Lors d'une nouvelle session, restaurez-les avec %store -r.
ipcluster - Calcul Parallèle
IPython offre des capacités de calcul parallèle via ipcluster. Commencez par lancer des moteurs parallèles :
ipcluster start -n 4 # Lance 4 moteurs IPython pour le calcul parallèle
Exemple de Comptage de Mots Parallélisé
Considérons un fichier texte volumineux, par exemple mon_grand_texte.txt, et nous voulons compter la fréquence des mots.
D'abord, les fonctions de traitement de texte de base :
import re
import io
from collections import defaultdict
# Motif pour les caractères spéciaux (non-mots)
special_chars_pattern = re.compile(r'[\W\d_]+', re.UNICODE)
# Liste de mots fréquents à ignorer
frequent_words = {
'le', 'la', 'les', 'un', 'une', 'des', 'de', 'du', 'd', 'et', 'à', 'est',
'il', 'elle', 'on', 'nous', 'vous', 'ils', 'elles', 'ce', 'cet', 'cette',
'ces', 'que', 'qui', 'quoi', 'où', 'quand', 'comment', 'pour', 'par',
'avec', 'sur', 'dans', 'en', 'mais', 'ou', 'ni', 'car', 'donc', 'or',
'si', 'comme', 'quand', 'lorsque', 'tandis', 'aussi', 'ainsi', 'alors',
'après', 'avant', 'depuis', 'pendant', 'toujours', 'jamais', 'souvent',
'rarement', 'très', 'plus', 'moins', 'peu', 'beaucoup', 'tout', 'toute',
'tous', 'toutes', 'même', 'autres', 'chaque', 'quelques', 'plusieurs',
'certains', 'certaines', 'chaque', 'chacun', 'chacune', 'y', 'en', 'ne', 'pas',
'plus', 'rien', 'mon', 'ma', 'mes', 'ton', 'ta', 'tes', 'son', 'sa', 'ses',
'notre', 'nos', 'votre', 'vos', 'leur', 'leurs'
}
def extract_words_from_file(file_path):
"""Générateur qui extrait et nettoie les mots d'un fichier."""
with io.open(file_path, encoding='utf-8', errors='ignore') as f:
for line_content in f:
for raw_word in line_content.split():
clean_word = special_chars_pattern.sub('', raw_word.lower())
if clean_word and clean_word not in frequent_words:
yield clean_word
def perform_word_count(file_path):
"""Compte la fréquence des mots dans un fichier donné."""
word_counts = defaultdict(int)
for word_token in extract_words_from_file(file_path):
word_counts[word_token] += 1
return word_counts
# Exemple d'exécution séquentielle
# %time total_counts_seq = perform_word_count('mon_grand_texte.txt')
Maintenant, l'approche parallèle avec IPython.parallel :
from IPython import parallel
# 1. Connexion au client IPython parallèle
client = parallel.Client()
engine_ids = client.ids # IDs des moteurs disponibles
print(f"Moteurs IPython disponibles: {engine_ids}")
# Création d'une vue load-balanced
view_lb = client.load_balanced_view()
# 2. Diffusion des fonctions et données nécessaires aux moteurs
# Utilisez 'push' pour envoyer des variables aux moteurs
client[:].push(dict(
special_chars_pattern=special_chars_pattern,
frequent_words=frequent_words,
extract_words_from_file=extract_words_from_file,
perform_word_count=perform_word_count,
defaultdict=defaultdict, # defaultdict doit aussi être poussé
re=re, # et le module re
io=io # et le module io
))
# 3. Fonction pour diviser le fichier en morceaux plus petits
import os
def split_text_into_chunks(original_filename, num_chunks=len(engine_ids)):
"""Divise un fichier texte en plusieurs sous-fichiers pour le traitement parallèle."""
with open(original_filename, 'r', encoding='utf-8', errors='ignore') as f_orig:
all_lines = f_orig.readlines()
total_lines = len(all_lines)
chunk_size = total_lines // num_chunks
chunk_filenames = []
current_dir = os.path.abspath(os.getcwd())
for i in range(num_chunks):
start_line = i * chunk_size
end_line = (i + 1) * chunk_size if i < num_chunks - 1 else total_lines
chunk_content = "".join(all_lines[start_line:end_line])
chunk_file_path = os.path.join(current_dir, f"chunk_{i}.txt")
with open(chunk_file_path, 'w', encoding='utf-8') as f_chunk:
f_chunk.write(chunk_content)
chunk_filenames.append(chunk_file_path)
return chunk_filenames
# Créez un fichier bidon pour l'exemple si mon_grand_texte.txt n'existe pas
if not os.path.exists('mon_grand_texte.txt'):
with open('mon_grand_texte.txt', 'w', encoding='utf-8') as f:
for _ in range(10000): # 10000 lignes
f.write("Ceci est un exemple de ligne de texte pour le comptage de mots. " * 10 + "\n")
chunk_files = split_text_into_chunks('mon_grand_texte.txt')
print(f"Fichiers de fragments créés: {chunk_files}")
# 4. Exécution parallèle et agrégation des résultats
def aggregate_parallel_counts():
"""Exécute le comptage de mots en parallèle et aggrège les résultats."""
# map envoie la fonction perform_word_count à chaque moteur avec un fichier de fragment
async_results = view_lb.map(perform_word_count, chunk_files)
# Attend que tous les résultats soient prêts et les récupère
list_of_partial_counts = async_results.get()
final_word_counts = defaultdict(int)
for partial_counts in list_of_partial_counts:
for word, count in partial_counts.items():
final_word_counts[word] += count
return final_word_counts, async_results
# Mesure le temps d'exécution parallèle
print("\nDébut du comptage de mots parallèle...")
%time final_counts_parallel, parallel_res = aggregate_parallel_counts()
print(f"\nTemps écoulé pour la carte parallèle: {parallel_res.elapsed:.4f} secondes")
# print(f"Quelques mots et leurs fréquences: {list(final_counts_parallel.items())[:5]}")
# Nettoyage des fichiers de fragments
for f_path in chunk_files:
os.remove(f_path)