web-dev-qa-db-fra.com

Vérifiez si le fichier est lisible avec Python: essayez ou si / sinon?

J'ai le code suivant:

import glob, os
for file in glob.glob("\\*.txt"):
    if os.access(file, os.R_OK):
        # Do something
    else:
        if not os.access(file, os.R_OK):
            print(file, "is not readable")
        else:
            print("Something went wrong with file/dir", file)
        break

Mais je ne suis pas tout à fait sûr que ce soit la bonne façon de le faire. Est-il préférable d'utiliser try et catch l'erreur? Si oui, comment puis-je essayer pour plus de lisibilité? Notez le break dans ma déclaration else. Dès qu'un fichier ne peut pas être lu, je veux interrompre la boucle.

20
Bram Vanroy

Pour moi, utiliser un try-except dans la même portée que l'on utiliserait un if-else ne gagne aucune lisibilité. La valeur des exceptions est qu'elles peuvent être interceptées à un niveau supérieur dans l'arborescence des appels.

En sortant d'un seul niveau, nous évitons l'instruction break:

import glob, os
try:
    for file in glob.glob("\\*.txt"):
        with open(file) as fp:
            # do something with file
except IOError:
    print("could not read", file)

Mais le véritable génie des exceptions, c'est quand le code disparaît tout simplement:

# Operate on several files
# SUCCESS: Returns None
# FAIL: Raises exception
def do_some_files():
    for file in glob.glob("\\*.txt"):
        with open(file) as fp:
            # do something with file

Il incombe maintenant au programme appelant d'afficher un message d'erreur utile en cas d'échec. Nous avons supprimé la responsabilité de traiter les échecs complètement hors de ce code et dans un tout autre domaine.

En fait, on peut déplacer la responsabilité complètement hors de notre programme et dans l'interprète. Dans ce cas, l'interpréteur affichera un message d'erreur utile et mettra fin à notre programme. Si le message par défaut de Python est assez bon pour vos utilisateurs, je recommande de ne pas vérifier les erreurs pas du tout. Ainsi, votre script original devient:

import glob, os
for file in glob.glob("\\*.txt"):
    # Do something
12
Robᵩ

Un moyen plus explicite de vérifier si file est en fait un fichier et non un répertoire par exemple, et il est lisible:

from os import access, R_OK
from os.path import isfile

file = "/some/path/to/file"

assert isfile(file) and access(file, R_OK), \
       "File {} doesn't exist or isn't readable".format(file)
22
Tagar

Dans Python culture, il est plus courant de demander pardon, pas de permission , il est donc préférable d'attraper l'exception:

for filename in glob.glob('*.txt'):
    try:
        with open(filename) as fp:
            # work with the file

    except IOError as err:
        print "Error reading the file {0}: {1}".format(filename, err)
        break

De cette façon, vous éviterez également toute double vérification ou condition de course.

5
bereal
try:
        # check to see if file is readable
        with open(filename) as tempFile:





except Exception as e:
        print e
        # here you can modify the error message to your liking

C'est généralement ce que je fais. Il est robuste et simple

1
user126885