2014-07-08 15 views
9

Ich versuche, einige Informationen von Webseiten, die inkonsistent über wo sind die Informationen befindet kratzen. Ich habe Code, um mit jeder von mehreren Möglichkeiten umzugehen; was ich will, ist, sie nacheinander zu versuchen, und wenn keiner von ihnen funktioniert, würde ich gern scheitern und weitermachen.Python versuchen/außer: versuchen, mehrere Optionen

Das heißt, in psuedo-Code:

try: 
    info = look_in_first_place() 
otherwise try: 
    info = look in_second_place() 
otherwise try: 
    info = look_in_third_place() 
except AttributeError: 
    info = "Info not found" 

ich dies mit verschachtelten try-Anweisungen tun könnte, aber wenn ich 15 Möglichkeiten müssen versuchen, dann werde ich 15 Ebene der Vertiefung brauchen!

Das scheint eine trivial genug Frage zu sein, dass ich fühle, dass ich etwas vermisse, aber ich habe es in den Boden gesucht und kann nichts finden, das dieser Situation ähnlich aussieht. Gibt es einen vernünftigen und pythonischen Weg, dies zu tun?

EDIT: Wie Johns (ziemlich gute) Lösung unten anhebt, habe ich für die Kürze jedes Nachschlagen oben als einen einzelnen Funktionsaufruf geschrieben, während es in Wirklichkeit normalerweise ein kleiner Block von BeautifulSoup-Anrufen wie soup.find('h1', class_='parselikeHeader') ist. Natürlich könnte ich diese in Funktionen einpacken, aber es scheint ein bisschen unelegant mit solchen einfachen Blöcken - Entschuldigung, wenn meine Kurzschrift das Problem jedoch ändert.

Dies kann eine nützlichere Darstellung sein:

try: 
    info = soup.find('h1', class_='parselikeHeader').get('href') 
if that fails try: 
    marker = soup.find('span', class_='header') 
    info = '_'.join(marker.stripped_strings) 
if that fails try: 
    (other options) 
except AttributeError: 
    info = "Info not found" 
+0

warum brauchen Sie einen Try/außer, verwenden, wenn elif sonst –

+0

Dank Padraic, aber zusätzlich zu einem Instinkt EAFP über LYBL zu bevorzugen, ich bin nicht sicher, ob ich in der Lage sein würde, die, wenn die Bedingungen vorherzusagen zu überprüfen, wie es auf viele verschiedene Arten schief gehen konnte, so schien es eine natürliche Angemessenheit, mit einer begrenzten Anzahl von Ausnahmen umzugehen. – user3816044

+0

find wird leer sein, wenn es nichts ergibt, also wenn find ... nur True ist, wenn es eine Übereinstimmung gibt, wenn elif else sonst arbeiten würde. Sie könnten alle Muster in eine Liste einfügen und mit if check und ein anderes, wenn keines passt –

Antwort

8

Wenn jeder Lookup eine eigene Funktion ist, können Sie alle Funktionen in einer Liste speichern und dann über sie eins nach dem anderen durchlaufen.

lookups = [ 
    look_in_first_place, 
    look_in_second_place, 
    look_in_third_place 
] 

info = None 

for lookup in lookups: 
    try: 
     info = lookup() 
     # exit the loop on success 
     break  
    except AttributeError: 
     # repeat the loop on failure 
     continue 

# when the loop is finished, check if we found a result or not 
if info: 
    # success 
else: 
    # failure 
+0

Ich mag das, aber im Moment ist der Lookup-Code nicht wirklich in separaten Funktionen, sondern ist in der Regel 2-3 Zeilen BeautifulSoup Anrufe. Ich denke, ich könnte Wrapper für all die Möglichkeiten schreiben, aber das scheint übertrieben zu sein, da ich nach einigen Bits von Informationen suche, von denen jede mehrere Lookups haben kann ... Die Listenstrategie scheint sehr pythonisch zu sein, also kann ich sie benutzen Wenn ich keine bessere Lösung finde. – user3816044

+0

Wenn ich darüber nachdenke, würde es auf diese Weise bedeuten, dass die späteren Funktionen immer nur nützlich sein könnten, wenn sie in der bestimmten Reihenfolge aufgerufen werden, die die Liste spezifiziert (wenn ich zum Beispiel jeden weiteren Versuch permissiver machen möchte). Wenn Funktionen herumliegen, die schlechte Daten erzeugen, außer sie werden direkt nach einer anderen Funktion verwendet, scheint es, als könnte es eine gefährliche Einkapselungsstrategie sein. – user3816044

Verwandte Themen