8 façons d'utiliser la fonction open() de Python
Liens rapides
- Ouvrir un fichier et en lire le contenu
- Utilisation du mot-clé with pour fermer un fichier automatiquement
- Copier un fichier en lisant et en écrivant
- Créer un nouveau fichier texte
- Écrire dans un fichier journal en ajoutant
- Utilisez la mise en tampon pour contrôler l'enregistrement des fichiers
- Spécifiez un encodage pour un support UTF-8 correct
- Gérer les fichiers mal formés en utilisant le paramètre Errors
La fonction open de Python devrait être votre premier recours lorsque vous souhaitez lire le contenu d'un fichier. Donnez-lui un nom de fichier et vous obtiendrez un objet polyvalent, vous permettant de lire et d'écrire des données, à la fois en texte clair et en formats binaires.
Ces exemples montrent à quel point la fonction est flexible, avec le support de différents modes, du buffering, de l'encodage, et plus encore.
Ouvrir un fichier et en lire le contenu
La fonction open() a une signature assez compliquée, mais dans les cas les plus simples, vous pouvez l'utiliser pour ouvrir un fichier texte comme ceci :
f = open(filename)
Par défaut, Python ouvre ce fichier en mode lecture, ce qui signifie que vous ne pouvez que le lire. Cela est idéal pour les fichiers de configuration, les fichiers de données statiques, et ... Cela rend également ce cas courant concis et facile à retenir.
La fonction open() renvoie un objet fichier que vous pouvez ensuite utiliser pour effectuer diverses tâches, y compris la lecture du contenu complet d’un fichier :
f = open("/usr/share/dict/words")
text = f.read()
print(text)
Notez que ce simple extrait de code provoquera une exception en Python si le fichier n'existe pas :
Un fichier dont l'existence est garantie est le script que vous exécutez, que Python rend disponible dans la variable spéciale __file__. Cela facilite l'écriture d'un script qui imprime son propre code source, également appelé quine :
f = open(__file__)
text = f.read()
print(text)
Si vous êtes vraiment strict, ce n'est pas tout à fait un quine car lire un fichier est considéré comme de la triche.
Utilisation du mot-clé with pour fermer automatiquement un fichier
Lorsque Python ouvre un fichier, il alloue des ressources système à ce fichier, qu'il utilise ensuite pour des opérations futures comme la lecture et l'écriture. Si votre programme s'exécute jusqu'à la fin, Python devrait libérer ces ressources, les rendant disponibles pour d'autres processus qui pourraient s'exécuter sur votre système. Mais cela n'est pas garanti, donc vous devriez toujours vous assurer que les ressources sont correctement libérées. Le moyen le plus simple de le faire est d'appeler explicitement la méthode close() sur votre fichier lorsque vous savez que vous avez terminé de travailler avec :
f = open("/usr/share/dict/words")
text = f.read()
f.close()
Essayez de fermer un fichier dès que vous le pouvez. Par exemple, si vous ouvrez un fichier, lisez son contenu, puis traitez ce contenu, essayez de fermer le fichier dès que vous avez lu son contenu. Il n’est pas nécessaire de garder le fichier ouvert pendant que vous traitez les données que vous avez lues dans une variable.
Mais des problèmes peuvent encore survenir : que se passe-t-il si l'appel à close() ne s'exécute pas correctement ? Pour contourner ce problème, vous devriez utiliser le mot-clé with. Cela crée un gestionnaire de contexte pour le bloc qu'il enveloppe, ce qui garantit que les ressources du fichier sont libérées :
with open("/usr/share/dict/words") as f:
text = f.read()
Copier un fichier en lisant et en écrivant
Diverses bibliothèques Python offrent des moyens de copier un fichier, donc cet exemple est purement illustratif. Il montre l'utilisation du deuxième argument de open, mode. Cet argument indique à open comment vous prévoyez d'utiliser le fichier. Vous pouvez utiliser n'importe quelle combinaison valide de ces caractères :
Personnage | Signification |
|---|---|
r | Lire |
w | Écrire |
x | Créer et écrire |
a | Ajouter |
b | Binaire |
t | Texte |
+ | Mettre à jour |
Le mode par défaut est rt—lire un fichier texte—c’est pourquoi le premier exemple de cet article a fonctionné comme prévu. Pour copier le fichier que vous avez lu, vous devrez ouvrir un second fichier en utilisant le mode w pour écrire. Vous devrez également utiliser le mode b pour les deux afin de garantir que les opérations de lecture et d’écriture respectent les données binaires.
source = "./image.jpg"
target = "./a-copy-of-image.jpg"
with open(source, "rb") as src, open(target, "wb") as tgt:
buffer = src.read()
tgt.write(buffer)
Le bloc with agit sur les deux fichiers, donc il les fermera automatiquement une fois terminé.
Alors que la fonction open de Python vous donne un accès de bas niveau au contenu d'un fichier, le module os fournit de nombreuses fonctions de niveau supérieur qui opèrent sur les fichiers et le système de fichiers.
Créer un nouveau fichier texte
Vous pouvez également utiliser l'argument mode pour créer un nouveau fichier, mais protéger tout fichier portant le même nom qui pourrait déjà exister :
open(filename, "x")
Si un fichier du même nom existe déjà, cet appel à open générera une exception FileExistsError. Il s'agit d'une bonne mesure préventive qui évite la nécessité de vérifier explicitement l'existence du fichier :
# Warning: don't do this!
import os.path
filename = "example.txt"
if os.path.isfile(filename):
print("Sorry, file already exists")
else:
with open(filename, "w") as f:
# ...
À part le fait de devoir écrire un peu moins de code, il y a cependant une raison encore meilleure d'utiliser le mode « x » : il permet d'éviter une condition de concurrence. Considérons l'exemple ci-dessus, qui comporte une instruction qui vérifie si le fichier existe (if os.path.isfile(filename)) suivie d'une autre instruction qui l'ouvre pour l'écriture (with open(filename, "w") as f). Si un autre processus fait quelque chose avec ce fichier entre ces deux instructions, un désastre peut survenir.
Ouvrir un fichier en mode création peut éviter un désastre, car une seule instruction est responsable de vérifier le fichier et de l'ouvrir. Soit elle échoue, et le fichier existant est protégé, soit elle réussit, et aucun autre processus ne peut créer un autre fichier du même nom entre-temps.
Écrire dans un fichier journal en ajoutant
Par défaut, un fichier que vous ouvrez en mode écriture sera d'abord tronqué, de sorte que son contenu sera écrasé. Pour ajouter du contenu à un fichier à la place, vous pouvez utiliser le mode ajout :
log = open("file.log", "a")
Encore une fois, la journalisation en Python est mieux gérée avec le module logging, qui s'occupe de nombreux détails délicats. Cependant, à titre d'exemple, vous pouvez consigner dans un fichier en utilisant un code similaire à celui-ci :
def startup():
print("Just a dummy")
def main():
print("Doing the main thing")
return 42
def log(msg):
logfile.write(msg + "\n")
logfile = open("file.log", "w")
log("starting startup")
startup()
log("startup finished")
log("starting main")
ret = main()
log("main finished: " + str(ret))
logfile.close()
Utilisez la mise en tampon pour contrôler l'enregistrement des fichiers
Pour éviter de rouvrir et d'enregistrer constamment le même fichier, l'exemple de journalisation utilise une variable globale et un gestionnaire de fichier de longue durée. Cela semble correct dans un exemple simple, mais dans une situation réelle, votre programme peut s'exécuter indéfiniment, et vous pouvez vouloir vérifier ce fichier journal à tout moment. Si vous le faites, vous pourriez être surpris :
while True:
log(random.random())
input("Press Enter to continue")
Ce code imite la journalisation périodique d'un processus de longue durée. Vous pouvez contrôler sa journalisation en appuyant sur Entrée lorsque vous souhaitez qu'une autre ligne soit enregistrée. Cependant, si vous l'exécutez, vous devriez remarquer un gros défaut : si vous appuyez sur Entrée plusieurs fois et consultez le fichier journal, vous verrez que rien n'y est écrit !
La commande tail—plus précisément, tail -f—peut vous aider à suivre les modifications d'un fichier journal en temps réel.
Si vous appuyez sur Entrée suffisamment de fois, vous devriez finalement voir quelques résultats car la sortie aura dépassé la taille de tampon par défaut de Python. Sur mon système, cela correspond à 8192 octets, ce qui prendra beaucoup de temps à s'accumuler.
Heureusement, pour des cas comme celui-ci, il existe l'argument de mise en mémoire tampon, qui vous permet de définir la politique de mise en mémoire tampon. Dans le cas d'un fichier journal, une excellente approche à adopter est la mise en mémoire tampon par ligne, ce qui
Essayez d'exécuter l'exemple précédent avec une petite modification :
logfile = open("file.log", "w", 1)
Le troisième argument, 1, spécifie le tamponnement par ligne. Avec cette option activée, vous devriez voir que le fichier journal se met à jour chaque fois que la fonction log() s'exécute, car elle inclut un caractère de nouvelle ligne à la fin lorsqu'elle écrit dans le fichier.
Spécifiez un encodage pour un support UTF-8 approprié
Le codage des caractères est un sujet complexe, mais la domination actuelle de UTF-8 signifie que vous aurez rarement à vous en préoccuper. Cependant, certains systèmes hérités peuvent utiliser d'autres codages, et vous ne savez jamais ce qui pourrait apparaître à l'avenir. Les erreurs de codage peuvent causer de gros problèmes.
UTF-16 est une alternative à UTF-8 qui est plus efficace pour certains types de texte. La plupart des textes écrits en anglais sont mieux adaptés à UTF-8, mais les textes dans d'autres langues, ou les collections de symboles—comme un fichier rempli d'émojis—seront plus petits s'ils sont stockés en UTF-16.
Si vous essayez d'ouvrir un fichier UTF-16 en utilisant l'approche standard d'ouverture, vous verrez une erreur :
La fonction open—avec quelques réserves—attend par défaut un encodage UTF-8, donc vous devrez spécifier l'encodage pour ouvrir un fichier UTF-16 :
f = open("../utf16-file.txt", encoding="utf-16")
En utilisant un argument nommé, vous pouvez laisser les arguments mode et buffering à leurs valeurs par défaut. Sinon, vous pouvez fournir des valeurs par défaut (ou personnalisées) pour ceux-ci :
f = open("../utf16-file.txt", "r", -1, "utf-16")
Même si vous ouvrez un fichier UTF-8, il est conseillé de déclarer explicitement l'encodage en utilisant cet argument. Certains systèmes d'exploitation (par exemple, Windows) peuvent utiliser un encodage non UTF-8, il est donc prudent de ne pas se fier à la valeur par défaut.
Gérer les fichiers mal formés en utilisant le paramètre Errors
Bien que vous deviez veiller à spécifier un encodage, cela peut ne pas toujours être possible. Mais la fonction open n'est pas obligée d'échouer en cas d'erreurs d'encodage ; vous pouvez utiliser l'argument errors pour choisir son comportement parmi plusieurs options.
La valeur par défaut est 'strict', ce qui déclenche une exception, mais vous pouvez ignorer complètement ces erreurs avec 'ignore':
f = open("../utf16-file.txt", errors='ignore')
L'inconvénient est que vous pourriez maintenant être confronté à des données corrompues, sans le savoir. La possibilité de gérer cela dépendra de la nature de vos données.
Une alternative courante consiste à remplacer les caractères invalides par un caractère indiquant qu'ils sont manquants, généralement un point d'interrogation. Vous avez peut-être remarqué ce comportement sur certaines pages web qui n'ont pas spécifié correctement leur encodage. La valeur 'replace' pour l'argument errors fera exactement cela.
Enfin, la valeur 'backslashreplace' remplacera chaque caractère malformé par son équivalent sous forme de séquence d'échappement Python avec une barre oblique inversée. Cela peut vous aider à déboguer la cause originale du problème, donc cela pourrait être utile pour les tests ou dans le cadre d'une suite d'outils de développement.


