2015-08-18 9 views
12

Mam następujący kod:Sprawdź, czy plik jest czytelny w Pythonie: spróbuj lub czy/else?

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 

Ale nie jestem do końca pewien, czy to dobry sposób, żeby to zrobić. Czy lepiej jest używać błędu try i catch? Jeśli tak, jak mogę spróbuj dla czytelności? Zwróć uwagę na break w mojej instrukcji else. Jak tylko plik nie może zostać odczytany, chcę przerwać pętlę.

+6

można spróbować otwarcie pliku do odczytu i przechwytywanie wynikowego wyjątku (jeśli istnieje). Byłoby to również bardziej niezawodne niż obecne podejście, ponieważ plik może stać się nieczytelny (lub nawet zniknąć) między dwoma wywołaniami "os.access()". –

+2

Czy rzeczywiście czytasz plik w sekcji "#Do wykonania czegoś" lub czy chcesz tylko sprawdzić jego czytelność? –

+0

@ PM2Ring Właściwie to czytam tam plik. –

Odpowiedz

7

Dla mnie, używając try-except w tym samym zakresie, w którym użyto if-else, nie zyskuje czytelności. Wartością wyjątków jest to, że mogą one zostać przechwycone na wyższym poziomie w drzewie wywołań.

Poruszanie się tylko jeden poziom, unikamy oświadczenie 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) 

Ale prawdziwy geniusz wyjątków jest, gdy kod po prostu znika:

# 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 

Teraz jest odpowiedzialność programu wywołującego wyświetlać przydatny komunikat o błędzie po awarii. Usunęliśmy odpowiedzialność za uporanie się z awarią całkowicie poza tym kodem i całą inną dziedziną.

W rzeczywistości można całkowicie przenieść odpowiedzialność z naszego programu i do tłumacza. W takim przypadku interpreter wyświetli kilka przydatnych komunikatów o błędach i zakończy nasz program. Jeśli domyślny komunikat Pythona jest wystarczająco dobry dla użytkowników, nie zaleca się sprawdzania błędów w ogóle. Tak więc, oryginalny scenariusz staje:

import glob, os 
for file in glob.glob("\\*.txt"): 
    # Do something 
+1

Twoje kung-fu jest lepsze, muszę przyznać. – bereal

+0

Jako odpowiedź na ostatnią sugestię, czy interpreter nie będzie pomijać nieczytelnych plików zamiast zatrzymywać pętlę i zatrzymywać? Ponieważ nigdy nie definiujemy, co musimy zrobić, gdy wystąpi błąd –

+0

Nie, @BramVanroy, ostatni krótki skrypt nie pominie nieczytelnych plików. Domniemane 'open()' wewnątrz '#Do Something' podniosłoby wyjątek podczas próby otwarcia nieczytelnego pliku.Ten wyjątek zostanie przechwycony przez interpreter, który wyświetli komunikat o błędzie i wyjdzie. To jest, nieprzypadkowo, dokładnie to, co robi program w twoim pytaniu: wydrukuj komunikat o błędzie i zakończ. Jedyną różnicą między zachowaniem mojej krótkiej wersji a twoją długą wersją jest tekst komunikatu o błędzie. –

0
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 

Zwykle to robię. Jest wytrzymała i prosta

+0

Ups, że problem należy rozwiązać teraz – user126885

+0

Nigdy nie używaj "wyjątku wyjątku" bez prostego "podbijania" tuż po tym! – Ben

4

w Pythonie kultury, jest to bardziej powszechne ask forgiveness, not permission, więc lepiej jest złapać wyjątek:

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 

ten sposób można również uniknąć podwójnego sprawdzenia czy warunki wyścigu.

9

bardziej wyraźny sposób, aby sprawdzić, czy file jest w rzeczywistości plik, a nie katalog na przykład, że jest czytelny:

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)