Python: les fichiers (2/3) – le module os

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

Lorsque j’ouvre un fichier en mode écriture et que ce dernier n’existe pas, alors il est créé dans le répertoire courant, c’est-à dire à l’endroit ou le script est lancé. Prenons un exemple concret.

#!/usr/bin/env python3
# -*- coding: utf8 -*-

bonjour = "Bonjour et bienvenue dans mon antre!"
with open('test_file', 'w') as file_:
    file_.write(bonjour)
print(bonjour)

Bonjour et bienvenue dans mon antre!

  • Mon script s’appelle fichier_2.py.
  • Il se trouve dans /home/benoit qui est donc le répertoire courant.
  • Le chemin absolu du script est /home/benoit/fichier_2.py
  • Le chemin relatif est fichier_2.py.
  • Dans ce script, j’ai ouvert (en écriture) un fichier test_file dans lequel j’ai écrit le contenu de la variable bonjour. Le fichier test_file est créé par défaut dans le répertoire courant car j’ai utilisé son chemin relatif.

Si je veux connaitre le répertoire courant, il me faut importer le module os et faire appel à la méthode os.getcwd(). Cela signifie get current working directory. (= obtenir le répertoire courant)

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os

cwd = os.getcwd()
print(cwd)
bonjour = "Bonjour et bienvenue dans mon antre!"
print(bonjour)

/home/benoit
Bonjour et bienvenue dans mon antre!

Le répertoire courant, c’est-à dire l’endroit où le script est lancé, est donc /home/benoit. Si je lance le script dans un émulateur de terminal, il me suffit de taper ./fichier_2.py.

terminal_fichier_2

Déplacement du script dans mon dossier /home/benoit/Documents.

À présent, je vais déplacer ce script intitulé fichier_2.py dans mon dossier Documents. Le chemin absolu devient donc:

/home/benoit/Documents/fichier_2.py

Que devient le répertoire courant? Faisons le test en reprenant le code:

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os

cwd = os.getcwd()
print(cwd)
bonjour = "Bonjour et bienvenue dans mon antre!"
with open('test_file', 'w') as file_:
    file_.write(bonjour)
print(bonjour)

Dans un environnement de développement intégré IDLE3

Si je lance le script à l’aide de l’environnement de développement intégré IDLE3, le répertoire courant devient /home/benoit/Documents. Quant au fichier test_file, il est créé dans ce répertoire courant.

  • Son chemin absolu est donc /home/benoit/Documents/test_file.
  • Son chemin relatif est test_file.

Dans un émulateur de terminal

Par contre, si je lance le script dans un un émulateur de terminal, le répertoire courant est toujours /home/benoit par défaut. Et le fichier test_file est créé dans ce répertoire courant.

  • Son chemin absolu est donc /home/benoit/test_file.
  • Son chemin relatif est test_file.

Pour ce qui est du script fichier_2.py:

  • son chemin absolu est  /home/benoit/Documents/fichier_2.py
  • son chemin relatif devient Documents/fichier_2.py

terminal_fichier_2_2

Tout ceci pour vous dire que cette histoire de répertoire courant peut s’avérer un peu déroutante pour celui qui se lance dans l’apprentissage du Python.

D’aucuns vont me dire qu’il suffit de toujours utiliser le chemin absolu pour ouvrir un fichier mais ce n’est pas une bonne idée. Pourquoi donc? parce que si vous exportez votre programme chez un autre utilisateur, son répertoire courant sera différent (sauf coup de bol) et votre programme ne s’exécutera pas.

Par exemple, le chemin absolu du fichier test_file que je viens de créer en utilisant un émulateur de terminal est : /home/benoit/test_file. Or, tout le monde ne s’appelle pas Benoît. Certains s’appellent Sigismond, Côme, Alceste ou Antiphane. C’est leur droit. Du coup, il y a fort à parier qu’un tel script ne s’exécutera pas (à cause de la ligne 5):

#!/usr/bin/env python3
# -*- coding: utf8 -*-

bonjour = "Bonjour et bienvenue dans mon antre!"
with open('/home/benoit/test_file', 'w') as file_:
    file_.write(bonjour)

De toute manière, il faut savoir que toutes les opérations sur des fichiers s’effectuent systématiquement en se basant sur le répertoire courant dès que le nom du fichier passé n’est pas un chemin absolu (donc dès qu’il ne démarre pas par / sur les systèmes Posix ou x:\ sous Windows). Par conséquent, le code ci-dessous s’exécutera sur n’importe quel ordinateur :

#!/usr/bin/env python3
# -*- coding: utf8 -*-

bonjour = "Bonjour et bienvenue dans mon antre!"
with open('test_file', 'w') as file_:
    file_.write(bonjour)

Changer de répertoire avec os.chdir() et la commande cd

la commande cd fournie par l’interpréteur en ligne de commande Bash

Cette commande bash s’utilise dans un émulateur de terminal et elle permet de modifier le répertoire courant. cd signifie change directory. Je rappelle que le répertoire courant d’un émulateur de terminal est toujours par défaut le répertoire utilisateur (/home/benoit en ce qui me concerne). Pour le modifier, il suffit par exemple de rentrer cd Documents et le répertoire courant deviendra /home/benoit/Documents. Observez la capture d’écran ci-dessous et constatez par vous-même que l’invite de commande à changé : benoit@benoit-GA-880GM-UDH:~/Documents$

cd

La méthode os.chdir()

On peut également modifier le répertoire courant dans le script grâce à la méthode os.chdir(). Là encore, chdir signifie change directory.

Les deux codes ci-dessous exécutent le même programme. Le script fichier_2.py est placé dans /home/benoit tandis que le chemin du fichier test_file est /home/benoit/Documents. Ce sont les lignes 5 et 8-9 qui nous intéressent.

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os
os.chdir(os.getcwd() + "/Documents")
cwd = os.getcwd()
print(cwd)
bonjour = "Bonjour et bienvenue dans mon antre!"
with open('test_file', 'w') as file_:
    file_.write(bonjour)

/home/benoit/Documents

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os
cwd = os.getcwd()
print(cwd)
bonjour = "Bonjour et bienvenue dans mon antre!"
with open('Documents/test_file', 'w') as file_:
    file_.write(bonjour)

/home/benoit

Aperçu de quelques méthodes du module os.path()

Le code ci-dessous vous montre quelques méthodes du module os.path, à savoir :

  • abspath() qui retourne le chemin absolu du fichier passé en argument.
  • basename() qui retourne le nom de base du chemin absolu d’un fichier passé en argument.
  • dirname() qui retourne le nom du répertoire parent du fichier passé en argument.
  • split() qui fractionne un chemin absolu passé en argument et retourne un tuple

Ce n’est qu’un aperçu. Il existe d’autres méthodes que je vous invite à découvrir en consultant la documentation officielle.

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os.path
os.chdir(os.getcwd() + "/Documents")
cwd = os.getcwd()

bonjour = "Bonjour et bienvenue dans mon antre!"
with open('test_file', 'w') as file_:
    file_.write(bonjour)

absolute_path = os.path.abspath('test_file')
basename = os.path.basename(absolute_path)
dirname = os.path.dirname(absolute_path)
split = os.path.split(absolute_path)

print("Répertoire courant = {}".format(cwd))
print("Chemin absolu = {}".format(absolute_path))
print("Nom de base = {}".format(basename))
print("Nom du répertoire parent = {}".format(dirname))
print("Fractionnement du chemin absolu = {}".format(split))

Répertoire courant = /home/benoit/Documents

Chemin absolu = /home/benoit/Documents/test_file
Nom de base = test_file
Nom du répertoire parent = /home/benoit/Documents
Fractionnement du chemin absolu = (‘/home/benoit/Documents’, ‘test_file’)

La méthode os.listdir()

Cette méthode retourne une liste contenant les noms de toutes les entrées d’un répertoire passé en argument. Je vais appliquer par exemple os.listdir() sur un de mes répertoires intitulé mon_jardin.

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os
print(os.listdir("/home/benoit/mon_jardin"))

[‘notes_tomates’, ‘note_number’, ‘species.py’, ‘entrylist’, ‘validated’, ‘images_fruits’, ‘images’, ‘legumes’, ‘entrees_agenda’, ‘phototheque.py’, ‘.gitkeep’, ‘images_legumes’, ‘calendrier.py’, ‘accueil.py’, ‘agenda.py’, ‘dossiers_images’, ‘__pycache__’, ‘jardin.desktop’, ‘fruits’, ‘README.md’, ‘module_notes.py’, ‘file_color’, ‘varietes_tomates’]

La méthode os.rename(src, dst)

Renomme le fichier ou le répertoire source (src)  en dst (destination).

#!/usr/bin/env python3
# -*- coding: utf8 -*-

import os
os.rename("/home/benoit/mon_jardin", "/home/benoit/mon_ordinateur")

mon_ordinateur

La méthode os.remove(path)

Supprime le chemin passé en argument (path). Si path est un répertoire, Python lève une exception. Pour supprimer un répertoire, il faut utiliser la commande os.rmdir() qui ne fonctionne que si le répertoire est vide! Si tel n’est pas le cas, Python lève là-encore une exception!

La méthode os.mkdir(path)

Cette méthode créé un répertoire nommé path.

#!/usr/bin/env python3

import os
os.mkdir('/home/benoit/ma_voiture')

ma_voiture

Python: les fichiers (1/3)

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

Introduction

Dans le chapitre 2, nous avons vu que les variables étaient des objets comparables à des tiroirs dans lesquels on pouvait déposer des données de différents types (nombres entiers, chaînes de caractères, etc…). Mais lorsque nous fermons notre programme, ces variables qui sont créées dans la RAM, c’est-à dire la mémoire vive de l’ordinateur, disparaissent corps et âmes. Il ne sert donc à rien d’y stocker des données que l’on souhaite conserver après la fermeture du programme puisque de toute façon, elles seront perdues. Comment faire alors?

La seule solution consiste à stocker les données que l’on souhaite conserver dans des fichiers qui se trouvent non pas dans la mémoire vive de l’ordinateur mais sur le disque dur.

files

Utilité d’un fichier

Prenons un exemple concret pour illustrer mon propos :

prenom = input("Entrez votre prénom: ")
print("Votre prénom est {}".format(prenom))

Votre prénom est Maxence

Dans ce premier bout de code, le programme demande à l’utilisateur de renseigner son prénom grâce à la fonction input(). La chaîne de caractères est ensuite stockée dans la variable prenom. Mais dès que nous quittons le programme, la variable prenom avec la chaîne de caractères Maxence, disparaît.

À présent, nous allons stocker le prénom de l’utilisateur dans un fichier conservé dans le répertoire courant sur le disque dur :

prenom = input("Entrez votre prénom: ")
file_ = open("utilisateur", 'w')
file_.write(prenom)
file_.close()
file_ = open("utilisateur", 'r')
first_name = file_.read()
file_.close()
print("Votre prénom est {}".format(first_name))

Votre prénom est Fulgent

Dans ce deuxième bout de code, j’ai créé sur mon disque dur (plus précisément dans le répertoire courant qui se nomme /home/benoit), un fichier utilisateur. Ce fichier récupère le prénom entré par l’utilisateur à savoir Fulgent. Le fichier a été créé en mode écriture (‘w’ = write). Ensuite, j’ai fermé le fichier et je l’ai réouvert en mode lecture (‘r’). J’ai stocké le prénom dans une variable intitulée first_name. J’ai fermé le fichier et j’ai fait appel à la fonction print() pour afficher le prénom.

Le fichier créé dans mon répertoire courant /home/benoit

utilisateur_2

Maintenant, je ferme le programme. La variable first_name qui stockait le prénom Fulgent a certes disparu mais comme j’ai pris soin de conserver l’information dans un fichier enregistré dans le répertoire courant sur mon disque dur, je peux très facilement rouvrir ce dernier et récupérer le prénom. Action!

file_ = open("utilisateur", 'r') # Ouverture du fichier en mode lecture
first_name = file_.read() # Stockage du contenu du fichier dans une variable
file_.close() # Fermeture du fichier
print("Votre prénom est {}".format(first_name))

Votre prénom est Fulgent

Mission accompli! Fulgent est toujours en vie.

L’objet-fichier _io.TextIOWrapper

Les fichiers peuvent être manipulés grâce à une interface qu’on appelle objet-fichier. Si on fait print(file_), on obtient ceci :

_io.TextIOWrapper name=’utilisateur’ mode=’r’ encoding=’UTF-8′

Dans le code ci-dessus, file_ est donc un objet de type _io.TextIOWrapper qui ouvre un fichier dont le nom est utilisateur, en mode lecture (‘r’). L’encodage est UTF-8.

Les différents modes d’ouverture

Le mode lecture (‘r’)

Le mode lecture (‘r’) est le mode d’ouverture par défaut c’est-à-dire que vous n’êtes pas obligé de le préciser :

file_ = open("utilisateur")

Le mode lecture permet d’appliquer plusieurs méthodes d’extraction de données que je vais vous présenter dans cet article.

Le mode écriture (‘w’) avec effacement préalable du fichier

‘w’ signifie write. Lorsqu’on utilise ce mode:

  • S’il n’existe pas, le fichier est d’abord créé et il s’agit d’un fichier vide.
  • Si le fichier existe déjà, celui-ci est vidé de son contenu au préalable et grâce à la méthode write(), on peut y écrire de nouvelles données.

Mon fichier utilisateur contient actuellement le prénom Fulgent. Je vais le remplacer par le prénom Toufik.

prenom = input("Entrez votre prénom: ")
file_ = open("utilisateur", 'w')
file_.write(prenom)
file_.close()
file_ = open("utilisateur", 'r')
first_name = file_.read()
file_.close()
print("Votre prénom est {}".format(first_name))

Entrez votre prénom: Toufik
Votre prénom est Toufik

Le contenu de mon fichier a été modifié. Fulgent a disparu et Toufik a pris sa place :

toufik

Le mode ajout (‘a’)

‘a’ signifie append. L’ouverture du fichier en mode ajout va créer un nouveau fichier vide de tout contenu si celui-ci n’existe pas. Si le fichier existe déjà, le mode ‘a’ permet l’écriture dans le fichier à la suite des données déjà présentes. Le contenu du fichier n’est donc pas écrasé au préalable.

prenom = input("Entrez votre prénom: ")
file_ = open("utilisateur", 'a')
file_.write(prenom)
file_.close()
file_ = open("utilisateur", 'r')
first_name = file_.read()
file_.close()
print("Le contenu du fichier est {}".format(first_name))

Entrez votre prénom: Helmut
Le contenu du fichier est ToufikHelmut

ToufikHelmut

Eh! Mais keskispass? ToufikHelmut!! C’est quoi le blème?

Il n’y a pas de blème. Le fichier est ouvert en mode append donc les nouvelles données sont écrites à la suite de celles déjà présentes. Si on veut que le nouveau prénom soit écrit sur une nouvelle ligne, alors il faut prendre soin de rajouter un caractère de saut de ligne ‘\n’. C’est ce que je fais à la troisième  et à la huitième ligne du code ci-dessous.

prenom = input("Entrez votre prénom: ")
file_ = open("utilisateur", 'a')
file_.write(prenom + '\n') # Rajout d'un saut de ligne
file_.close()
file_ = open("utilisateur", 'r')
first_name = file_.read()
file_.close()
print("Le contenu du fichier est:\n{}".format(first_name))

Entrez votre prénom: Toufik
Le contenu du fichier est:
Toufik

>>>
Entrez votre prénom: Helmut
Le contenu du fichier est:
Toufik
Helmut

Vérifions le fichier en question. Nous constatons que cette fois-ci, Helmut a bien été rajouté sur une nouvelle ligne:

helmut

Les modes d’ouverture de fichiers binaires

Dans le prochain chapitre, nous verrons qu’il est parfois nécessaire d’ouvrir des fichiers binaires. Pour ce faire, il existe des modes d’ouverture en binaire :

  • Le mode lecture : ‘rb’
  • Le mode écriture avec effacement préalable du contenu : ‘wb’
  • Le mode ajout : ‘ab’

La fonction intégrée open()

Lorsqu’on créé un objet-fichier, l’ouverture du fichier se fait grâce à la fonction intégrée open().

prenom = input("Entrez votre prénom: ")
file_ = open("utilisateur", 'a')

Refermer un fichier à l’aide de la méthode close()

Après avoir travaillé sur les données d’un fichier, il est nécessaire de refermer ce dernier afin qu’il puisse être disponible pour d’autres utilisations. C’est exactement comme un livre… Lorsque vous avez fini votre lecture, vous ne reposez pas le livre ouvert dans votre bibliothèque! Vous le refermez d’abord, n’est-ce pas?

Cette opération s’effectue grâce à la méthode close() que vous avez découverte dans les différents codes de cet article. Il ne faut pas oublier de refermer un fichier.

Nous verrons dans un prochain paragraphe qu’il existe une autre méthode d’ouverture avec une syntaxe un peu particulière (with open() as). Elle est très intéressante car elle permet de s’affranchir de la méthode close() grâce à l’indentation.

Écrire dans un fichier grâce la méthode write()

La méthode write(), appliquée sur un objet-fichier, permet d’écrire dans un fichier.

file_.write(prenom + '\n') # Écriture dans le fichier

Extraire les données d’un fichier pour les stocker dans une variable

Après avoir ouvert un fichier en mode lecture (‘r’), on peut appliquer sur l’objet-fichier diverses méthodes d’extraction de données.

La méthode read()

Dans les codes précédents, j’ai utilisé la méthode read(). Cette dernière extrait la totalité du contenu du fichier qu’elle retourne sous la forme d’une chaîne de caractères.

La méthode readline()

Cette méthode ne lit qu’une seule ligne à la fois et ne prend pas en compte le caractère de fin de ligne. Elle retourne une chaîne de caractères.

file_ = open("utilisateur", 'r')
first_name = file_.readline()
file_.close()
print("Le contenu du fichier est:\n{}".format(first_name))

Le contenu du fichier est:
Toufik

>>> print(file_.readline())
Helmut

>>> print(file_.readline())
Kevin

La méthode readlines()

La méthode readlines() extrait la totalité du fichier et retourne non pas une chaîne de caractères mais une liste sur laquelle il est possible ensuite d’effectuer une itération.

file_ = open("utilisateur", 'r')
first_name = file_.readlines()
file_.close()
print("Le contenu du fichier est:\n{}".format(first_name))

Le contenu du fichier est:
[‘Toufik\n’, ‘Helmut\n’]

À présent, grâce à une boucle for, je peux par exemple appliquer sur chaque élément de la liste, la méthode lower() pour mettre les prénoms en minuscules.

file_ = open("utilisateur", 'r')
first_name = file_.readlines()
file_.close()
file_ = open("utilisateur", 'w')
for i in first_name:
    file_.write(i.lower())
file_.close()

Les majuscules initiales ont disparu!

lower

La syntaxe with open() as

Dans la mesure du possible, je vous conseille vivement d’utiliser cette syntaxe pour ouvrir vos fichiers car elle a un gros avantage : il n’y a pas besoin d’utiliser la méthode close() pour refermer le fichier. Cette opération est effectuée automatiquement, à la sortie du bloc indenté. with open() as fonctionne comme ceci:

with open("fichier", 'mode') as objet_fichier:
    variable = objet_fichier.readlines() # BLOC INDENTÉ

Reprenons le code précédent et utilisons cette nouvelle syntaxe pour mettre Toufik et Helmut en majuscules à l’aide de la méthode upper():

with open("utilisateur", 'r') as file_:
    first_name = file_.readlines()
with open("utilisateur", 'w') as file_:
    for i in first_name:
        file_.write(i.upper())

TH

Vous constatez que tous les file_.close() ont disparu. Ils sont devenus inutiles. Les étourdis ne risquent donc pas d’oublier de refermer un fichier! Personnellement, j’utilise presque toujours cette syntaxe.

Conclusion

Les fichiers sont nécessaires pour conserver des données avant de quitter une application et pouvoir les réutiliser par la suite. Dans la deuxième partie de ce chapitre, nous ferons connaissance avec le module os et le module pickle.

#Python: 3126 pages, 13 cm d’épaisseur… Du lourd!

Lundi dernier, le facteur a eu bien du mal à glisser dans ma boite à lettres, le courrier qui m’était destiné. Et pour cause! Il s’agissait de deux grimoires de Mark Lutz intitulés Learning Python et Programming Python que j’avais commandés quelques jours auparavant. 3126 pages, 13 cm d’épaisseur, tout en anglais! Joie!

Ce diaporama nécessite JavaScript.

Continuer à lire … « #Python: 3126 pages, 13 cm d’épaisseur… Du lourd! »

framagit: une forge que j’ai découverte bien trop tard!

Bonjour à tous,

Voici un article qui va sembler bien naïf à tous les codeurs aguerris mais il se trouve que jusqu’ici, je déposais mes codes sur pastebin, un lieu de relégation où la poussière les recouvrait lentement. Continuer à lire … « framagit: une forge que j’ai découverte bien trop tard! »

#Python – Application « Mon jardin » : Analyse du code (1ère partie)

Edit du 04/04/2017

Je viens de déposer la totalité du code source sur Framagit : 

https://framagit.org/Ordinosor/mon-jardin/tree/master

Bonjour à tous, Continuer à lire … « #Python – Application « Mon jardin » : Analyse du code (1ère partie) »

Python : Mon application destinée aux jardiniers

Edit du 03/ 04/2017

Je viens de déposer la totalité du code source sur Framagit : 

https://framagit.org/Ordinosor/mon-jardin/tree/master

Bonjour, Continuer à lire … « Python : Mon application destinée aux jardiniers »

Python: Les booléens

Pour une lecture plus agréable (page plus large), je vous invite à cliquer sur ce lien et à lire ce chapitre dans la rubrique consacrée au langage Python.

Aujourd’hui, je vais vous parler des booléens. Les booléens sont des êtres farouches qui vivent au fin fond des forêts binaires recouvrant la terre sacrée du Grand Python Digital. Très difficiles à observer dans leur milieu naturel, bla, bla, bla… Continuer à lire … « Python: Les booléens »