« Programmation Python/Fichiers » : différence entre les versions

Contenu supprimé Contenu ajouté
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
Ligne 9 :
L'idée la plus simple consiste à placer chacun de ces textes dans une variable, en début de programme, avec des instructions d'affectation du genre :
 
<sourcesyntaxhighlight lang="Python">
a = "Quelle est la capitale du Guatémala ?"
b = "Qui a succédé à Henri IV ?"
c = "Combien font 26 × 43 ?"
etc.
</syntaxhighlight>
</source>
 
Cette idée est malheureusement beaucoup trop simpliste. Tout va se compliquer en effet lorsque nous essayerons d'élaborer la suite du programme, c'est-à-dire les instructions qui devront servir à sélectionner au hasard l'une ou l'autre de ces questions pour les présenter à l'utilisateur. Employer par exemple une longue suite d'instructions <code>if ... elif ... elif ...</code> comme dans l'exemple ci-dessous n'est certainement pas la bonne solution (ce serait d'ailleurs bien pénible à écrire : n'oubliez pas que nous souhaitons traiter un grand nombre de questions !) :
 
<sourcesyntaxhighlight lang="Python">
if choix == 1:
selection = a
Ligne 26 :
selection = c
... etc.
</syntaxhighlight>
</source>
 
La situation se présente déjà beaucoup mieux si nous faisons appel à une liste :
 
<sourcesyntaxhighlight lang="Python">
liste = ["Qui a vaincu Napoléon à Waterloo ?",
"Comment traduit-on 'informatique' en anglais ?",
"Quelle est la formule chimique du méthane ?", ... etc ...]
</syntaxhighlight>
</source>
 
On peut en effet extraire n'importe quel élément de cette liste à l'aide de son indice. Exemple :
 
<sourcesyntaxhighlight lang="Python">
print liste[2] ===> "Quelle est la formule chimique du méthane ?"
</syntaxhighlight>
</source>
 
(rappel : l'indiçage commence à partir de zéro)
Ligne 73 :
Si vous travaillez avec IDLE, vous souhaiterez donc certainement forcer Python à changer son répertoire courant, afin que celui-ci corresponde à vos attentes. Pour ce faire, utilisez les commandes suivantes en début de session. (Nous supposons ici que le répertoire visé est le répertoire <code>/home/jules/exercices</code>. Vous pouvez franchement utiliser cette syntaxe (c'est-à-dire des caractères / et non \ en guise de séparateurs : c'est la convention en vigueur dans le monde Unix). Python effectuera automatiquement les conversions nécessaires, suivant que vous travaillez sous MacOS, Linux, ou Windows.<ref>Dans le cas de Windows, vous pouvez également inclure dans ce chemin la lettre qui désigne le périphérique de stockage où se trouve le fichier. Par exemple : <code>D:/home/jules/exercices</code>.</ref>
 
<sourcesyntaxhighlight lang="Python">
>>> from os import chdir
>>> chdir("/home/jules/exercices")
</syntaxhighlight>
</source>
 
La première commande importe la fonction <code>chdir()</code> du module <code>os</code>. Le module <code>os</code> contient toute une série de fonctions permettant de dialoguer avec le système d'exploitation (os = ''operating system''), quel que soit celui-ci.
Ligne 96 :
Voici un exemple de la première méthode :
 
<sourcesyntaxhighlight lang="Python">
>>>>>> import os
>>> rep_cour = os.getcwd()
>>> print rep_cour
C:\Python22\essais
</syntaxhighlight>
</source>
 
La première ligne de cet exemple importe l'intégralité du module <code>os</code>, lequel contient de nombreuses fonctions intéressantes pour l'accès au système d'exploitation. La seconde ligne utilise la fonction <code>getcwd()</code> du module os<ref>Le point séparateur exprime donc ici une relation d'appartenance. Il s'agit d'un exemple de la ''qualification des noms'' qui sera de plus en plus largement exploitée dans la suite de ce cours. Relier ainsi des noms à l'aide de points est une manière de désigner sans ambiguïté des éléments faisant partie d'ensembles, lesquels peuvent eux-mêmes faire partie d'ensembles plus vastes, etc. Par exemple, l'étiquette <code>systeme.machin.truc</code> désigne l'élément <code>truc</code>, qui fait partie de l'ensemble <code>machin</code>, lequel fait lui-même partie de l'ensemble <code>systeme</code>. Nous verrons de nombreux exemples de cette technique de désignation, notamment lors de notre étude des classes d'objets.</ref>. Comme vous pouvez le constater, la fonction <code>getcwd()</code> renvoie le nom du répertoire courant (getcwd = ''get current working directory'').
Ligne 107 :
Par comparaison, voici un exemple similaire utilisant la seconde méthode d'importation :
 
<sourcesyntaxhighlight lang="Python">
>>> from os import getcwd
>>> rep_cour = getcwd()
>>> print rep_cour
C:\Python22\essais
</syntaxhighlight>
</source>
 
Dans ce nouvel exemple, nous n'avons importé du module <code>os</code> que la fonction <code>getcwd()</code> seule. Importée de cette manière, la fonction s'intègre à notre propre code comme si nous l'avions écrite nous-mêmes. Dans les lignes où nous l'utilisons, il n'est pas nécessaire de rappeler qu'elle fait partie du module <code>os</code>.
Ligne 118 :
Nous pouvons de la même manière importer plusieurs fonctions du même module :
 
<sourcesyntaxhighlight lang="Python">
>>> from math import sqrt, pi, sin, cos
>>> print pi
Ligne 126 :
>>> print sin(pi/6) # sinus d'un angle de 30°
0.5
</syntaxhighlight>
</source>
 
Nous pouvons même importer toutes les fonctions d'un module, comme dans :
 
<sourcesyntaxhighlight lang="Python">
from Tkinter import *
</syntaxhighlight>
</source>
 
Cette méthode d'importation présente l'avantage d'alléger l'écriture du code. Elle présente l'inconvénient (surtout dans sa dernière forme, celle qui importe toutes les fonctions d'un module) d'encombrer l'espace de noms courant. Il se pourrait alors que certaines fonctions importées aient le même nom que celui d'une variable définie par vous-même, ou encore le même nom qu'une fonction importée depuis un autre module. (Si cela se produit, l'un des deux noms en conflit n'est évidemment plus accessible).
Ligne 146 :
L'exemple ci-dessous vous montre comment ouvrir un fichier « en écriture », y enregistrer deux chaînes de caractères, puis le refermer. Notez bien que si le fichier n'existe pas encore, il sera créé automatiquement. Par contre, si le nom utilisé concerne un fichier préexistant qui contient déjà des données, les caractères que vous y enregistrerez viendront s'ajouter à la suite de ceux qui s'y trouvent déjà. Vous pouvez faire tout cet exercice directement à la ligne de commande :
 
<sourcesyntaxhighlight lang="Python">
>>> obFichier = open('Monfichier','a')
>>> obFichier.write('Bonjour, fichier !')
Ligne 152 :
>>> obFichier.close()
>>>
</syntaxhighlight>
</source>
 
;Notes
Ligne 169 :
Vous allez maintenant rouvrir le fichier, mais cette fois « en lecture », de manière à pouvoir y relire les informations que vous avez enregistrées dans l'étape précédente :
 
<sourcesyntaxhighlight lang="Python">
>>> ofi = open('Monfichier', 'r')
>>> t = ofi.read()
Ligne 175 :
Bonjour, fichier ! Quel beau temps, aujourd'hui !
>>> ofi.close()
</syntaxhighlight>
</source>
 
Comme on pouvait s'y attendre, la méthode <code>read()</code> lit les données présentes dans le fichier et les transfère dans une variable de type « chaîne » (''string'') . Si on utilise cette méthode sans argument, la totalité du fichier est transférée.
Ligne 184 :
<li>Le fichier que nous voulons lire s'appelle <code>Monfichier</code>. L'instruction d'ouverture de fichier devra donc nécessairement faire référence à ce nom-là. Si le fichier n'existe pas, nous obtenons un message d'erreur. Exemple :
 
<sourcesyntaxhighlight lang="Python">
>>> ofi = open('Monficier','r')
IOError: [Errno 2] No such file or directory: 'Monficier'
</syntaxhighlight>
</source>
 
Par contre, nous ne sommes tenus à aucune obligation concernant le nom à choisir pour l'objet-fichier. C'est un nom de variable quelconque. Ainsi donc, dans notre première instruction, nous avons choisi de créer un objet-fichier <code>ofi</code>, faisant référence au fichier réel <code>Monfichier</code>, lequel est ouvert en lecture (argument <code>r</code>).</li>
Ligne 195 :
<li>La méthode <code>read()</code> peut également être utilisée avec un argument. Celui-ci indiquera combien de caractères doivent être lus, à partir de la position déjà atteinte dans le fichier :
 
<sourcesyntaxhighlight lang="Python">
>>> ofi = open('Monfichier', 'r')
>>> t = ofi.read(7)
Ligne 203 :
>>> print t
, fichier !Quel
</syntaxhighlight>
</source>
 
 
S'il ne reste pas assez de caractères au fichier pour satisfaire la demande, la lecture s'arrête tout simplement à la fin du fichier :
 
<sourcesyntaxhighlight lang="Python">
>>> t = ofi.read(1000)
>>> print t
beau temps, aujourd'hui !
</syntaxhighlight>
</source>
 
Si la fin du fichier est déjà atteinte, <code>read()</code> renvoie une chaîne vide :
 
<sourcesyntaxhighlight lang="Python">
>>> t = ofi.read()
>>> print t
Ligne 222 :
 
>>> ofi.close()
</sourcesyntaxhighlight></li>
</ul>
 
Ligne 231 :
La fonction ci-dessous illustre cette idée. Elle copie l'intégralité d'un fichier, quelle que soit sa taille, en transférant des portions de 50 caractères à la fois :
 
<sourcesyntaxhighlight lang="Python">
def copieFichier(source, destination):
"copie intégrale d'un fichier"
Ligne 244 :
fd.close()
return
</syntaxhighlight>
</source>
 
Si vous voulez tester cette fonction, vous devez lui fournir deux arguments : le premier est le nom du fichier original, le second est le nom à donner au fichier qui accueillera la copie. Exemple :
 
<sourcesyntaxhighlight lang="Python">
copieFichier('Monfichier','Tonfichier')
</syntaxhighlight>
</source>
 
== Fichiers texte ==
Ligne 258 :
Il est très facile de traiter ce genre de fichiers sous Python. Les instructions suivantes créent un fichier texte de quatre lignes :
 
<sourcesyntaxhighlight lang="Python">
>>> f = open("Fichiertexte", "w")
>>> f.write("Ceci est la ligne un\nVoici la ligne deux\n")
>>> f.write("Voici la ligne trois\nVoici la ligne quatre\n")
>>> f.close()
</syntaxhighlight>
</source>
Notez bien le marqueur de fin de ligne <code>\n</code> inséré dans les chaînes de caractères, aux endroits où l'on souhaite séparer les lignes de texte dans l'enregistrement. Sans ce marqueur, les caractères seraient enregistrés les uns à la suite des autres, comme dans les exemples précédents.
Ligne 269 :
Lors des opérations de lecture, les lignes d'un fichier texte peuvent être extraites séparément les unes des autres. La méthode <code>readline()</code>, par exemple, ne lit qu'une seule ligne à la fois (en incluant le caractère de fin de ligne) :
 
<sourcesyntaxhighlight lang="Python">
>>> f = open('Fichiertexte','r')
>>> t = f.readline()
Ligne 276 :
>>> print f.readline()
Voici la ligne deux
</syntaxhighlight>
</source>
 
 
La méthode <code>readlines()</code> transfère toutes les lignes restantes dans une liste de chaînes :
 
<sourcesyntaxhighlight lang="Python">
>>> t = f.readlines()
>>> print t
['Voici la ligne trois\012', 'Voici la ligne quatre\012']
>>> f.close()
</syntaxhighlight>
</source>
 
;Remarques
Ligne 298 :
Le script qui suit vous montre comment créer une fonction destinée à effectuer un certain traitement sur un fichier texte. En l'occurrence, il s'agit ici de recopier un fichier texte en omettant toutes les lignes qui commencent par un caractère <code>#</code> :
 
<sourcesyntaxhighlight lang="Python">
def filtre(source,destination):
"recopier un fichier en éliminant les lignes de remarques"
Ligne 312 :
fd.close()
return
</syntaxhighlight>
</source>
 
Pour appeler cette fonction, vous devez utiliser deux arguments : le nom du fichier original, et le nom du fichier destiné à recevoir la copie filtrée. Exemple :
 
<sourcesyntaxhighlight lang="Python">
filtre('test.txt', 'test_f.txt')
</syntaxhighlight>
</source>
 
== Enregistrement et restitution de variables diverses ==
Ligne 326 :
Nous pouvons réaliser cela à l'aide de la fonction intégrée <code>str()</code> :
 
<sourcesyntaxhighlight lang="Python">
>>> x = 52
>>> f.write(str(x))
</syntaxhighlight>
</source>
 
Si nous enregistrons les valeurs numériques en les transformant d'abord en chaînes de caractères, nous risquons de ne plus pouvoir les re-transformer correctement en valeurs numériques lorsque nous allons relire le fichier. Exemple :
 
<sourcesyntaxhighlight lang="Python">
>>> a = 5
>>> b = 2.83
Ligne 346 :
52.8367
>>> f.close()
</syntaxhighlight>
</source>
 
Nous avons enregistré trois valeurs numériques. Mais comment pouvons-nous les distinguer dans la chaîne de caractères résultante, lorsque nous effectuons la lecture du fichier ? C'est impossible ! Rien ne nous indique d'ailleurs qu'il y a là trois valeurs plutôt qu'une seule, ou 2, ou 4,…
Ligne 352 :
Il existe plusieurs solutions à ce genre de problèmes. L'une des meilleures consiste à importer un module Python spécialisé : le module pickle<ref>En anglais, le terme ''pickle'' signifie "conserver". Le module a été nommé ainsi parce qu'il sert effectivement à enregistrer des données en conservant leur type.</ref>. Voici comment il s'utilise :
 
<sourcesyntaxhighlight lang="Python">
>>> import pickle
>>> f = open('Monfichier', 'wb')
Ligne 370 :
67 <type 'int'>
>>> f.close()
</syntaxhighlight>
</source>
 
Pour cet exemple, on considère que les variables <code>a</code>, <code>b</code> et <code>c</code> contiennent les mêmes valeurs que dans l'exemple précédent. La fonction <code>dump()</code> du module ''pickle'' attend deux arguments : le premier est la variable à enregistrer, le second est l'objet fichier dans lequel on travaille. La fonction <code>pickle.load()</code> effectue le travail inverse, c'est-à-dire la restitution de chaque variable avec son type.
Ligne 392 :
<li>Réfléchissez !</li>
<li>
<sourcesyntaxhighlight lang=python>
# Comptage du nombre de mots dans un texte
 
Ligne 409 :
fs.close()
print("Ce fichier texte contient un total de %s mots" % (n))
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang=python>
# Conversion en majuscule du premier caractère de chaque ligne
 
Ligne 439 :
fd.close()
fs.close()
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang=python>
# Fusion de lignes pour former des phrases
 
Ligne 472 :
fd.close()
fs.close()
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang=python>
# Caractéristiques de sphères :
# Le fichier de départ est un fichier <texte> dont chaque ligne contient
Ligne 507 :
fd.close()
fs.close()
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang=python>
# Mise en forme de données numériques
# Le fichier traité est un fichier <texte> dont chaque ligne contient un nombre
Ligne 540 :
fd.close()
fs.close()
</syntaxhighlight>
</source>
</li>
</ol>
Ligne 581 :
<ol>
<li>
<sourcesyntaxhighlight lang="Python">
#(éditeur simple, pour lire et écrire dans un fichier 'texte') :
def sansDC(ch):
Ligne 619 :
else:
lireDansFichier()
</syntaxhighlight>
</source>
</li>
<li>Réfléchissez !</li>
<li>
<sourcesyntaxhighlight lang="Python">
#(génération des tables de multiplication de 2 à 30) :
def tableMulti(n):
Ligne 672 :
fichier.writelines(lignes) # réenregistrement
fichier.close()
</syntaxhighlight>
</source>
</li>
<li>Réfléchissez !</li>
<li>
<sourcesyntaxhighlight lang="Python">
# Mise en forme de données numériques.
# Le fichier traité est un fichier texte dont chaque ligne contient un nombre
Ligne 729 :
else:
print "sont identiques."
</syntaxhighlight>
</source>
</li>
<li>Réfléchissez !</li>
<li>
<sourcesyntaxhighlight lang="Python">
# Combinaison de deux fichiers texte pour en faire un nouveau
 
Ligne 756 :
fiB.close()
fiC.close()
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang="Python">
# Enregistrer les coordonnées des membres d'un club
 
Ligne 797 :
 
of.close()
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang="Python">
# Ajouter des informations dans le fichier du club
 
Ligne 859 :
fd.close()
fs.close()
</syntaxhighlight>
</source>
</li>
<li>
<sourcesyntaxhighlight lang="Python">
# Recherche de lignes particulières dans un fichier texte :
 
Ligne 891 :
print ligne
fi.close()
</syntaxhighlight>
</source>
</li>
 
Ligne 940 :
 
Sauvegarde d'un dictionnaire :
<sourcesyntaxhighlight lang=python>
def enregistrement():
fich = raw_input("Entrez le nom du fichier de sauvegarde : ")
Ligne 969 :
dico[cle] = (age, taille) # reconstitution du dictionnaire
ofi.close()
</syntaxhighlight>
</source>
 
Ces deux fonctions peuvent être appelées respectivement à la fin et au début du programme principal, comme dans l'exemple ci-dessous :
 
<sourcesyntaxhighlight lang=python>
dico ={}
lectureFichier()
Ligne 985 :
consultation()
enregistrement()
</syntaxhighlight>
</source>
</li>
<li>
Cet exercice complète le précédent. On ajoute encore deux petites fonctions, et on réécrit le corps principal du programme pour diriger le flux d'exécution en se servant d'un dictionnaire :
<sourcesyntaxhighlight lang=python>
# Contrôle du flux d'exécution à l'aide d'un dictionnaire
def sortie():
Ligne 1 015 :
# Rem : toutes les fonctions appelées ici renvoient <None> par défaut,
# sauf la fonction sortie() qui renvoie 1 => sortie de la boucle
</syntaxhighlight>
</source>
</li>
</ol>
Ligne 1 021 :
 
== Lister des fichiers et dossiers ==
<sourcesyntaxhighlight lang=python>
items = os.walk(folder)
for root, directories, files in items:
Ligne 1 029 :
print(file)
return
</syntaxhighlight>
</source>
 
== Supprimer des fichiers et dossiers ==
<sourcesyntaxhighlight lang=python>
os.unlink(fichier)
# Pour un dossier vide :
Ligne 1 039 :
import shutil
shutil.rmtree(dossier)
</syntaxhighlight>
</source>
 
== Références ==