<jupyter_start><jupyter_text>Introduction à Python > présentée par <NAME> Ce n'est pas toujours très pratique d'enregistrer les données directement dans le code *(hard-coding)*. Il est souvent plus facile de lire les données depuis un fichier (comme un tableur au format csv). Nous allons essayer d'écrire la liste des personnes avec lesquelles nous avons travaillé précédemment dans un fichier. Puis nous allons essayer de reconstruire l'information pour la manipuler avec python.  Manipulation de fichiers Python fournit nativement une fonction `open` pour manipuler les fichiers. Elle retourne un `file object` qui dispose de certaines méthodes spécifiques, un peu comme nos objets *Personne* avec leur méthode `age()`. La fonction `open()` prend le nom du fichier comme premier argument arbitraire, et un tas d'options dont la plus utile est le mode de lecture du fichier (qui va définir la façon dont python va pouvoir manipuler le fichier : *read*, *write*, *append*) Note : [voir la liste de toutes les fonctions natives de python](https://docs.python.org/3/library/functions.html) Note : [voir la documentation de la fonction `open()`](https://docs.python.org/3/library/functions.htmlopen)  Ecriture dans un fichier<jupyter_code># solution naive
fichier = open("data/fichiers/nom_du_fichier.txt", mode="w")  # mode write
fichier.write("La première ligne d'une longue histoire...")  # là, on appelle la méthode write de l'object de type 'file object'
fichier.close()  # on ferme le fichier<jupyter_output><empty_output><jupyter_text>La fermeture du fichier est importante pour libérer immédiatement les ressources systèmes utilisées par celui-ci. Note : Si vous ne fermez pas explicitement un fichier, le *garbage collector* de Python (une stratégie de python qui s'occupe de la gestion de la mémoire) finit par détruire l'objet et fermer le fichier ouvert, mais le fichier peut rester ouvert pendant un certain temps. Le risque associé est que différentes implémentations de Python effectuent ce nettoyage à différents moments, ce qui signifie que votre programme peut ne plus marcher d'une version à l'autre...  Petite disgression et introduction à la notion de contexte Comme c'est un peu pénible d'appeler des fonctions de manière répétitive (ou tout de moins celles auxquelles on ne pense pas toujours...), python a rajouté le mot clé natif `with` qui permet de gérer un contexte. `with` appelle la fonction `__enter__()` d'un objet quand on entre dans le contexte, et sa fonction `__exit__()` quand on en sort. On pourrait voir la fonction open comme un objet implémenté commme ci:```pyclass File(object):     Une fausse implémentation de la classe File, juste pour comprendre    def __init__(self, filename, mode="r"):        self.filename = filename        self.mode = mode    def __enter__(self):        self.open_file = open(self.filename, self.mode)        return self.open_file    def __exit__(self):        self.open_file.close()``` Bref, voici comment utiliser un contexte avec les fichiers<jupyter_code># solution élégante
with open("data/fichiers/nom_du_fichier.txt", mode="w") as fichier:
    fichier.write("La première ligne d'une longue histoire...")
    
# Une fois qu'on sort du contexte, le fichier est fermé. Note: la variable 'fichier' existe toujours
with open("data/fichiers/nom_du_fichier.txt", mode="w") as fichier:
    fichier.write("La première ligne d'une longue histoire...")
    print("Est-ce que le fichier est fermé dans le contexte ? {}".format(fichier.closed))
    
print("Est-ce que le fichier est fermé en dehors du contexte ? {}".format(fichier.closed))<jupyter_output>Est-ce que le fichier est fermé dans le contexte ? False
Est-ce que le fichier est fermé en dehors du contexte ? True<jupyter_text>Lecture d'un fichier<jupyter_code># solution naive
fichier = open("data/fichiers/nom_du_fichier.txt", "r")
contenu = fichier.read()
fichier.close()

contenu
# solution élégante
with open("data/fichiers/nom_du_fichier.txt", "r") as fichier:
    contenu = fichier.read()
    
print(contenu)<jupyter_output>La première ligne d'une longue histoire...<jupyter_text>Les exceptions > Qu'arrive-t-il si le fichier n'existe pas ? Python génère une erreur. On les appelle des exceptions. Si vous n'en n'avez pas encore rencontré : - soit vous suivez un tutoriel qui vous cache la véritée d'une vie de développeur. - soit vous n'avez pas encore essayer de programmer par vous même.Note : nous avions rencontrée une exception à la fin du premier chapitre. Cette introduction à python est clairement bien faite! > Comment faire en sorte pour que, dans le pire des cas (le fichier n'existe pas), on soit capable d'afficher la valeur de la variable `contenu` ?<jupyter_code>try:  # Exécute les déclarations suivantes.
    with open("un_nom_de_fichier_qui_n_existe_pas.txt", "r") as fichier:
        contenu = fichier.read()
except FileNotFoundError as error:  # Exécute les déclarations suivantes si une exception de type FileNotFoundError est soulevée.
    contenu = None

print("Contenu : {}".format(contenu))<jupyter_output>Contenu : None
{'fraction_non_alphanumeric': 0.07983441750443525, 'fraction_numerical': 0.0003942440370589395, 'mean_word_length': 4.832183908045977, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '504396', 'license': 'MIT', 'n_tokens_mistral': 1620, 'n_tokens_neox': 1623, 'n_words': 632, 'path': '07_Snippets.ipynb', 'repo_name': 'Tofull/introduction_python', 'size': '5078'}