8 façons d'utiliser la fonction Python Open ()
La fonction ouverte de Python devrait être votre premier port d'appel lorsque vous cherchez à lire le contenu d'un fichier. Donnez-lui un nom de fichier et vous récupérerez un objet polyvalent, vous permettant de lire et d'écrire des données, à la fois dans des formats de texte brut et binaires.
Ces exemples montrent à quel point la fonction est flexible, avec le support pour différents modes, tampons, codage, etc.
Sommaire
Ouvrez un fichier et lisez son 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 en lire plus que. Ceci 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 de fichier que vous pouvez ensuite utiliser pour effectuer diverses tâches, notamment la lecture du contenu complet d'un fichier:
f = open("/usr/share/dict/words")
text = f.read()
print(text)
Notez que cet extrait simple entraînera une exception de Python si le fichier n'existe pas:
Un fichier qui est garanti pour exister est le script que vous exécutez, que Python rend disponible dans le spécial __Variable de fichier__. Cela rend simple à écrire un script qui imprime son propre code source, autrement connu sous le nom de Quine:
f = open(__file__)
text = f.read()
print(text)
Si vous êtes vraiment strict, ce n'est pas tout à fait une quine car la lecture d'un fichier est considérée comme de la triche.
Utilisation du mot-clé avec pour fermer automatiquement un fichier
Lorsque Python ouvre un fichier, il alloue les ressources système à ce fichier, qu'il utilise ensuite pour les opérations futures comme la lecture et l'écriture. Si votre programme fonctionne jusqu'à la fin, Python devrait nettoyer ces ressources, ce qui les rend à la disposition d'autres processus qui peuvent fonctionner sur votre système. Mais ce n'est pas garanti, vous devez donc toujours vous assurer que les ressources sont nettoyées correctement. La façon la plus simple de le faire est d'appeler explicitement la méthode Close () sur votre fichier lorsque vous savez que vous avez fini de travailler avec:
f = open("/usr/share/dict/words")
text = f.read()
f.close()
Visez à fermer un fichier dès que vous le pouvez. Par exemple, si vous ouvrez un fichier, lisez son contenu, puis traitez le 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 se produire: que se passe-t-il si l'appel à fermer () ne fonctionne pas correctement? Pour contourner ce problème, vous devez utiliser le mot-clé avec. Cela crée un gestionnaire de contexte pour le bloc qu'il enveloppe, ce qui garantit que les ressources de fichiers sont libérées:
with open("/usr/share/dict/words") as f:
text = f.read()
Copiez un fichier en lisant et en écrivant
Diverses bibliothèques Python fournissent des moyens de copier un fichier, donc cet exemple est purement illustratif. Il démontre l'utilisation du deuxième argument d'Open, Mode. Cet argument indique à Open comment vous avez l'intention 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 |
|
un |
Ajouter |
|
b |
Binaire |
|
t |
Texte |
|
+ |
Mise à jour |
Le mode par défaut est RT – Lisez un fichier texte – c'est pourquoi le premier exemple de cet article a fonctionné comme vous vous en doutez. Pour copier le fichier que vous lisez, vous devrez ouvrir un deuxième fichier à l'aide du mode W pour écrire. Vous devrez également utiliser le mode B pour 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 avec le bloc fonctionne sur les deux fichiers, il les fera donc automatiquement une fois qu'il se terminera.
Créer un nouveau fichier texte
Vous pouvez également utiliser l'argument du mode pour créer un nouveau fichier, mais protéger tout fichier du même nom qui peut déjà exister:
open(filename, "x")
Si un fichier du même nom existe déjà, cet appel ouvert lancera une exception FileExistSerror. Il s'agit d'une bonne mesure défensive qui évite la nécessité de vérifier explicitement l'existence du fichier:
import os.path
filename = "example.txt"
if os.path.isfile(filename):
print("Sorry, file already exists")
else:
with open(filename, "w") as f:
En plus d'avoir à écrire un peu moins de code, cependant, il y a une raison encore meilleure d'utiliser le mode « X »: il évite une condition de course. Considérez l'exemple ci-dessus, qui a une instruction qui vérifie si le fichier existe (Si os.path.isfile (nom de fichier)) suivi d'une autre déclaration qui l'ouvre pour l'écriture (avec ouvert (nom de fichier, « w ») comme f). Si un autre processus fait quelque chose avec ce fichier entre ces deux instructions, une catastrophe peut se produire.
L'ouverture d'un fichier en mode Création peut éviter une catastrophe car une seule instruction est responsable de la vérification du fichier et de l'ouverture. Soit il échoue, et le fichier existant est protégé, soit il réussit, et aucun autre processus ne peut créer un autre fichier du même nom en attendant.
Écrivez dans un fichier journal en ajoutant
Par défaut, un fichier que vous ouvrez en mode écriture sera tronqué en premier, donc son contenu sera écrasé. Pour ajouter à un fichier à la place, vous pouvez utiliser le mode annexe:
log = open("file.log", "a")
Encore une fois, la connexion à Python est mieux gérée avec le module de journalisation, qui s'occupe de nombreux détails maladroits. Cependant, à titre d'exemple, vous pouvez vous connecter à 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 mémoire tampon pour contrôler l'enregistrement des fichiers
Pour éviter la réouverture et l'enregistrement constamment du même fichier, l'exemple de journalisation utilise une variable globale et une poignée de fichiers à longue durée de vie. Cela semble correct dans un exemple simple, mais dans une situation réelle, votre programme peut s'exécuter indéfiniment, et vous voudrez peut-être 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 date. Vous pouvez contrôler sa journalisation en appuyant sur Entrée lorsque vous voulez 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 vérifiez le fichier journal, vous verrez que rien ne s'y est écrit!
La commande de queue – en particulier, queue -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 enfin voir certains résultats car la sortie aura dépassé la taille du tampon par défaut de Python. Sur mon système, il s'agit de 8192 octets, qui prendra beaucoup de temps à s'accumuler.
Heureusement, pour des cas comme celui-ci, il y a l'argument tampon, qui vous permet de définir la politique tampon. Dans le cas d'un fichier journal, une grande approche à adopter est la tampon de ligne, qui
Essayez d'exécuter l'exemple précédent avec un minuscule ajustement:
logfile = open("file.log", "w", 1)
Le troisième argument, 1, spécifie la mise en mémoire tampon de ligne. Avec cette activité, vous devez voir que le fichier journal se met à jour chaque fois que la fonction log () s'exécute car elle inclut un caractère Newline traînant lorsqu'il écrit dans le fichier.
Spécifiez un codage pour un support UTF-8 approprié
L'encodage des personnages est un sujet compliqué, mais la domination d'aujourd'hui de l'UTF-8 signifie que vous aurez rarement besoin de vous en inquiéter. Cependant, certains systèmes hérités peuvent utiliser d'autres encodages, et vous ne savez jamais ce qui pourrait survenir à l'avenir. Les erreurs avec l'encodage peuvent causer de gros problèmes.
L'UTF-16 est une alternative à l'UTF-8 qui est plus efficace pour certains types de texte. La plupart des texte écrits en anglais sont mieux adaptés à l'UTF-8, mais le texte dans d'autres langues, ou des collections de symboles – comme un fichier plein d'emoji – sera plus petit s'ils sont stockés comme UTF-16.
Si vous essayez d'ouvrir un fichier UTF-16 en utilisant l'approche ouverte standard, vous verrez une erreur:
La fonction ouverte – avec quelques mises en garde – montre un codage UTF-8 par défaut, vous devrez donc spécifier le codage pour ouvrir un fichier UTF-16:
f = open("../utf16-file.txt", encoding="utf-16")
À l'aide d'un argument nommé, vous pouvez laisser le mode et les arguments tampon comme leurs défauts. Alternativement, vous pouvez fournir des valeurs par défaut (ou personnalisées) pour eux:
f = open("../utf16-file.txt", "r", -1, "utf-16")
Même si vous ouvrez un fichier UTF-8, c'est une bonne idée de déclarer explicitement l'encodage en utilisant cet argument. Certains systèmes d'exploitation (par exemple, Windows) peuvent utiliser un codage non UTF-8, il est donc sage de ne pas compter sur la valeur par défaut.
Gérer les fichiers mal formés à l'aide du paramètre Erreurs
Bien que vous deviez prendre soin de spécifier un encodage, ce n'est peut-être pas toujours possible. Mais la fonction ouverte n'a pas à échouer dans le cas des erreurs de codage; vous pouvez utiliser le erreurs Argument pour sélectionner son comportement à partir de plusieurs options.
La valeur par défaut est «stricte», ce qui soulève une exception, mais vous pouvez ignorer complètement ces erreurs avec «ignorer»:
f = open("../utf16-file.txt", errors='ignore')
L'inconvénient est que vous pouvez désormais faire face à des données corrompues, sans le savoir. Que ce soit quelque chose que vous pouvez gérer dépendra de la nature de vos données.
Une alternative commune consiste à remplacer les caractères non valides par un caractère indiquant qu'ils manquent, généralement un point d'interrogation. Vous avez peut-être repéré ce comportement sur la page Web occasionnelle qui n'a pas précisé son codage correctement. La valeur «Remplacer» pour l'argument des erreurs fera exactement cela.
Enfin, la valeur «arrière» remplacera chaque caractère malformé par son équivalent en tant que séquence d'échappement en arrière Python. Cela peut vous aider à déboguer la cause initiale du problème, il pourrait donc être utile pour les tests ou dans le cadre d'une suite de Dev Tools.
