Ce n'est pas spécifique à Python.
L'objectif des exceptions est de traiter le problème aussi près que possible de son origine.
Vous gardez donc le code qui, dans des circonstances exceptionnelles, pourrait déclencher le problème et la résolution "à côté" l'un de l'autre.
Le problème, c'est qu'il est impossible de connaître toutes les exceptions qui peuvent être levées par un morceau de code. Tout ce que vous pouvez savoir, c'est que s'il s'agit d'une exception de type "fichier non trouvé", vous pouvez la piéger et demander à l'utilisateur d'en trouver un qui fonctionne ou d'annuler la fonction.
Si vous mettez un try catch autour de cela, alors peu importe le problème qu'il y avait dans votre routine de fichier (lecture seule, permissions, UAC, pas vraiment un pdf, etc.), tout le monde tombera sur votre catch de fichier non trouvé, et votre utilisateur criera "mais il est là, ce code est merdique".
Il y a maintenant quelques situations où vous pouvez tout attraper, mais elles doivent être choisies consciemment.
Il s'agit d'attraper, d'annuler une action locale (comme la création ou le verrouillage d'une ressource, (l'ouverture d'un fichier sur le disque pour l'écriture par exemple), puis de relancer l'exception pour qu'elle soit traitée à un niveau supérieur).
L'autre toi est que tu ne te soucies pas de savoir pourquoi ça a mal tourné. L'impression par exemple. Vous pourriez avoir un piège autour de cela, pour dire Il y a un problème avec votre imprimante, veuillez le régler, et ne pas tuer l'application à cause de cela. De la même manière, si votre code exécutait une série de tâches séparées en utilisant une sorte de programme, vous ne voudriez pas que l'ensemble de l'application s'arrête parce que l'une des tâches a échoué.
Remarque Si vous faites ce qui précède, je ne saurais trop vous recommander une sorte de journalisation des exceptions, par exemple try catch log end.