HOWTO · Python
Lire la dernière ligne du fichier à l'aide de Python
Nous pouvons utiliser la boucle for et la fonction file.readlines() pour lire la dernière ligne d'un fichier en Python.
Sur cette page
Pour obtenir la dernière ligne en Python, parcourez le fichier et conservez la ligne lue le plus récemment. Cette méthode lit le fichier du début à la fin, mais ne garde qu’une ligne à la fois en mémoire. Si le fichier est très volumineux et que cette lecture complète est trop lente, lisez-le à rebours par blocs binaires.
Exécutez cet exemple. Les blocs de code sont conservés tels quels; leurs libellés visibles restent en anglais.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_text("alpha\nbeta\ngamma\n", encoding="utf-8")
last_line = None
with path.open("r", encoding="utf-8") as file:
for line in file:
last_line = line.rstrip("\r\n")
print(last_line)
gamma
Lire la dernière ligne d’un fichier en Python
Les objets fichier de Python ne proposent pas d’opération directe pour lire la « dernière ligne ». Une lecture ligne par ligne est simple et demande peu de mémoire supplémentaire, mais elle doit tout de même atteindre la fin du fichier. Si le fichier tient confortablement en mémoire, readlines() est plus concis; pour un fichier volumineux, une lecture binaire à rebours peut éviter de lire le contenu précédent. Le meilleur choix dépend de ce qui compte le plus : la simplicité, la mémoire utilisée ou le fait d’éviter une lecture complète.
Lire ligne par ligne avec une boucle for
Conservez dans une variable la ligne lue le plus récemment. En l’initialisant à None, le code renvoie une valeur définie lorsque le fichier ne contient aucune ligne. rstrip("\r\n") supprime uniquement les caractères de fin de ligne et préserve donc les espaces qui font partie du contenu.
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_text("first\nsecond\n", encoding="utf-8")
last_line = None
with path.open("r", encoding="utf-8") as file:
for line in file:
last_line = line.rstrip("\r\n")
print(last_line)
La boucle lit toutes les lignes : le temps nécessaire augmente donc avec la taille du fichier. La mémoire supplémentaire se limite à la ligne en cours et au résultat conservé. Un saut de ligne final ne crée pas de ligne supplémentaire dans l’itérateur de texte de Python; en revanche, si deux caractères de saut de ligne représentent une dernière ligne vide, celle-ci est renvoyée sous la forme d’une chaîne vide.
Utiliser readlines() pour les petits fichiers
readlines() renvoie toutes les lignes dans une liste, ce qui permet de sélectionner facilement le dernier élément. Vérifiez que la liste n’est pas vide avant d’y accéder par index, car un fichier sans contenu produit une liste vide. En mode texte, les fins de ligne restent dans les chaînes renvoyées; supprimez uniquement \r et \n si vous voulez obtenir le contenu sans son terminateur.
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_text("first\nsecond\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines = file.readlines()
last_line = lines[-1].rstrip("\r\n") if lines else None
print(last_line)
Cette méthode lit elle aussi tout le fichier et conserve toutes les lignes en mémoire. Utilisez-la si la liste vous est utile ailleurs ou si le fichier est de taille modeste; évitez strip() si les espaces au début ou à la fin peuvent avoir un sens.
Ne conserver que la dernière ligne avec deque
Un deque avec maxlen=1 élimine les éléments précédents à mesure que chaque nouvelle ligne arrive. Il effectue la même lecture séquentielle et utilise aussi peu de mémoire que la boucle, tout en nécessitant moins de gestion explicite de l’état. Vérifiez le résultat avant d’appeler pop() afin que la fonction gère également un fichier sans lignes.
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
from collections import deque
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_text("first\nsecond\n", encoding="utf-8")
with path.open("r", encoding="utf-8") as file:
lines = deque(file, maxlen=1)
last_line = lines.pop().rstrip("\r\n") if lines else None
print(last_line)
deque limite le nombre de lignes conservées, pas la quantité de données lues : la lecture atteint toujours la fin du fichier. C’est utile lorsque vous souhaitez ne garder que l’élément le plus récent pendant la lecture en continu d’un fichier.
Lire à rebours depuis la fin avec seek()
Pour un fichier volumineux, l’ouvrir en mode binaire permet à seek() de se déplacer sans risque entre les positions en octets. La fonction ci-dessous commence à la fin, retire un saut de ligne final s’il y en a un, puis recherche le saut de ligne précédent en remontant par blocs de taille fixe. Elle ne rassemble que les blocs qui contiennent la dernière ligne; la mémoire utilisée dépend donc de la longueur de cette ligne, et non de la taille totale du fichier. Cette méthode prend en charge les fins de ligne LF et CRLF et décode les octets sélectionnés avec l’encodage demandé.
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
from pathlib import Path
from tempfile import TemporaryDirectory
def read_last_line(path, encoding="utf-8", chunk_size=8192):
if chunk_size <= 0:
raise ValueError("chunk_size must be positive")
with open(path, "rb") as file:
file.seek(0, 2)
end = file.tell()
if end == 0:
return None
file.seek(end - 1)
position = end - 1 if file.read(1) == b"\n" else end
chunks = []
while position > 0:
start = max(0, position - chunk_size)
file.seek(start)
chunk = file.read(position - start)
newline = chunk.rfind(b"\n")
if newline >= 0:
chunks.append(chunk[newline + 1:])
line = b"".join(reversed(chunks))
return (line[:-1] if line.endswith(b"\r") else line).decode(encoding)
chunks.append(chunk)
position = start
line = b"".join(reversed(chunks))
return (line[:-1] if line.endswith(b"\r") else line).decode(encoding)
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.txt"
path.write_bytes("first\r\nlast line\r\n".encode("utf-8"))
print(read_last_line(path))
Si une ligne dépasse la taille d’un bloc, les blocs sont accumulés jusqu’à la découverte de son délimiteur; si le fichier ne contient qu’une ligne, la lecture remonte jusqu’au début. La ligne sélectionnée doit être valide dans l’encodage indiqué. Cette implémentation considère LF et CRLF comme des délimiteurs, mais pas les fichiers où le caractère CR seul sépare les lignes. Pour les encodages ou conventions de fin de ligne inhabituels, utilisez un lecteur de texte en continu ou adaptez le traitement des délimiteurs.
Utiliser tail sur les systèmes de type Unix
Sur les systèmes qui le proposent, la commande externe tail peut renvoyer la dernière ligne sans que vous ayez à implémenter vous-même une lecture à rebours. Depuis Python, récupérez ses octets avec subprocess.run(["tail", "-n", "1", path], capture_output=True, check=True), puis décodez result.stdout avec l’encodage du fichier. Cette méthode suppose que tail est installé et disponible dans PATH; elle ne constitue pas une solution native sous Windows. Utilisez une liste d’arguments au lieu de construire une commande shell à partir d’un chemin. Le comportement et la vitesse de la commande dépendent du système d’exploitation et du fichier.
Choisir une méthode et gérer les cas particuliers
| Méthode | Lit tout le fichier ? | Mémoire supplémentaire | À utiliser quand… |
|---|---|---|---|
Boucle for |
Oui | Une ligne | Vous voulez un code de lecture en continu simple. |
readlines() |
Oui | Toutes les lignes | Le fichier est petit ou la liste est nécessaire. |
deque avec maxlen=1 |
Oui | Une ligne | Vous voulez gérer l’état de lecture en continu de façon concise. |
Blocs binaires lus à rebours avec seek() |
Généralement non; peut remonter jusqu’au début si la dernière ligne est longue | Dernière ligne et un bloc | Le fichier est volumineux et utilise LF ou CRLF. |
tail |
Cela dépend de l’implémentation | Processus externe | La commande est disponible sur le système cible. |
Pour un fichier vide, renvoyez None ou une autre valeur de remplacement documentée au lieu d’indexer une liste ou d’appeler pop() sans vérification. Déterminez si le résultat doit inclure son terminateur de ligne; sinon, supprimez uniquement \r et \n. La boucle et deque utilisent peu de mémoire, mais lisent tout le fichier. readlines() est l’option basée sur une liste la plus simple pour les petits fichiers. Utilisez la lecture à rebours avec seek() lorsque vous devez éviter de lire le contenu précédent et que les hypothèses sur l’encodage et les fins de ligne conviennent au fichier. Choisissez tail si un utilitaire externe de type Unix est acceptable.