Python: Wie viel Code packt man in ein try/except

OP (Firma: RUB) #4594145
Lesenswert?

Joa, eigentlich ganz einfach Frage:
Wie viel Code packt man in ein try/except?

Kommt in das try nur die eine Funktion rein, die eine Exception auslösen 
kann, oder auch alles danach?
So:
1
def find_files(path):
2
    file_list = []
3
    try:
4
        files = os.listdir(path)
5
    except FileNotFoundError:
6
        return file_list
7

8
    for f in files:
9
        if os.path.isfile(path + f):
10
            file_list.append(f)
11

12
    return file_list

Oder eher so:
1
def find_files(path):
2
    file_list = []
3
    try:
4
        files = os.listdir(path)
5
        for f in files:
6
            if os.path.isfile(path + f):
7
                file_list.append(f)
8
    except FileNotFoundError:
9
        pass
10

11
    return file_list

Wie handhabt Ihr das?

Grüße
#4594165
Lesenswert?

Wenn Code auf das Ergebnis der Funktion welche die Exeption auslösen 
kann angewiesen ist dann kannst du den auch gleich mit dort 
reinschreiben damit er nich mit ausgeführt wird.
Wenn deine Funktion bei einem Fehler allerdings sowieso abgebrochen 
wird, dann kannst du den Code auch ausserhalb stehen lassen und deine 
Funktion in der Exception beenden.
Bei deinem Beispiel ist die 1. Variante eher schlecht, wenn die Funktion 
noch andere als die abgefangene Exception auslösen kann.

Sascha
Gast #4594753
Lesenswert?

Wie von Sascha bereits begründet - Alles ins try packen.

Ein return mitten in der Funktion ist ja verpönt. Trotzdem empfinde ich 
ein "return []" im except als die klarste Lösung. Bei dem "return 
file_list" und dem "pass" sieht man nicht, ob eine teilweise gefüllte 
Liste geliefert wird.
Gast #4596163
Lesenswert?

Python biete noch eine 3 Möglichkeit, das try kann ein else haben welche 
ausgeführt wird wenn die execption nicht auslöst. Soweit ich das 
verstanden habe ist die Design Idee dahinter genau die das das Except 
nahe beim try steht und man eine Hilfskonstruktion via Flags oder 
ähnliches spart.
1
def find_files(path):
2
    file_list = []
3
    try:
4
        files = os.listdir(path)
5
    except FileNotFoundError:
6
        pass
7
    else: 
8
        for f in files:
9
            if os.path.isfile(path + f):
10
                file_list.append(f)
11
    
12
    return file_list
Gast #4596373
Lesenswert?

porgamer schrieb:
>> Ein return mitten in der Funktion ist ja verpönt.
>
> Nur von Schwätzern.

Klar, wenn man übersichtlich und lesbar programmiert, könnte ja ein 
anderer den Code verstehen. Sowas muss man als Programmierer unter allen 
Umständen verhindern. So sichert man den eigenen Arbeitsplatz.

Georg
#4596433
Lesenswert?

Georg schrieb:
> Klar, wenn man übersichtlich und lesbar programmiert, könnte ja ein
> anderer den Code verstehen.

Ich benutze return innerhalb von Funktionen am laufenden Band, gerade 
weil ich es lesbarer finde.

Irgendwelche Conditions prüfen und falls diese nicht erfüllt sind, 
sofort die Funktion mit einem 'return false' oder einem Fehlercode 
verlassen. Das ist doch viel lesbarer und sicherer als das über 
temporäre Variablen und if-else zu lösen. Und das nur, damit am Ende der 
Funktion ein einziges return steht?
#4596452
Lesenswert?

Kaj G. schrieb:
>
1
>         if os.path.isfile(path + f):
2
>

Peng. {Hint: os.path.isfile(os.path.join(path, f))}

Ansonsten:
1
def find_file(path):
2
  try:
3
    return filter(os.path.isfile,
4
                  [os.path.join(path, f)
5
                   for f in os.listdir(path)])
6
  except FileNotFoundError, e:
7
    print str(e)
8
    return list()

oder, wenn Du keine Symlinks dabeihaben willst (os.path.isfile() gibt 
für Symlinks True zurück):
1
def find_file(path):
2
  try:
3
    return filter(lambda x: os.path.isfile(x)
4
                  and not os.path.islink(x),
5
                  [os.path.join(path, f)
6
                   for f in os.listdir(path)])
7
  except FileNotFoundError, e:
8
    print str(e)
9
    return list()
OP (Firma: RUB) #4596580
Lesenswert?

Sheeva P. schrieb:
> Peng. {Hint: os.path.isfile(os.path.join(path, f))}
Klaer mich auf, ich seh das Problem nicht.
Windows kann mit '/' im Pfad umgehen und da in path ein '/' am Ende 
steht, sehe ich nichts wo es knallen sollte.
Dazu macht es der zusaetzliche aufruf kein stueck lesbarer. :-/

Dazu ist der uebergebene Pfad an der Stelle immer relativ (Ja, das sieht 
man hier nicht).
Symlinks gibt es an der Stelle auch nicht (ja, ich weiss, das sieht man 
hier nicht). :)

Das mit filter und lambda ist ja auch ganz nett, macht es aber auch 
nicht lesbarer. :-/
#4596633
Lesenswert?

Kaj G. schrieb:
> Sheeva P. schrieb:
>> Peng. {Hint: os.path.isfile(os.path.join(path, f))}
> Klaer mich auf, ich seh das Problem nicht.
> Windows kann mit '/' im Pfad umgehen und da in path ein '/' am Ende
> steht, sehe ich nichts wo es knallen sollte.
> Dazu macht es der zusaetzliche aufruf kein stueck lesbarer. :-/

Wenn aus welchem Grund auch immer mal kein '/', ':' oder '\' am Ende 
steht, funktioniert die Version mit os.path.join() trotzdem korrekt, 
unabhängig von Eingabe und Plattform. Es bleibt aber natürlich Dir 
überlassen, ob Du robusten, fehlertoleranten, wiederverwendbaren und 
pattformunabhängigen Code schreiben willst. ;-)

> Dazu ist der uebergebene Pfad an der Stelle immer relativ (Ja, das sieht
> man hier nicht).
> Symlinks gibt es an der Stelle auch nicht (ja, ich weiss, das sieht man
> hier nicht). :)

Das spielt auch gar keine Rolle.

> Das mit filter und lambda ist ja auch ganz nett, macht es aber auch
> nicht lesbarer. :-/

Ich finde die Variante mit filter() auf die List Comprehension lesbarer, 
aber das ist wohl Gewohnheitssache. YMMV.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren