2016-06-07 12 views
0

Ich habe eine Datei mit folgendem Inhalt:Raise Ausnahme auf mehrere spezifischen "Strings", Python

XYZname_1

XYZname_2

XYZname_3

In meinem Skript Ich verwende einen re.search zu überprüfen Sie, ob die Namen falsch sind, wenn sie sind, mache ich eine raise exception. Wenn beide Namen inkorrekt sind, wird nur beim ersten Aufruf eine Ausnahme ausgelöst und dann "abgestürzt", mit anderen Worten, der "Benutzer" wird nicht wissen, ob der zweite oder dritte Name falsch ist.

for my_file in args.cpath: 
    contents = open(my_file).read() 

    replaced_contents = my_func(contents,my_file) 


def my_func(my_file_contents, filename): 
    for x in range(0, 3): 
     #Some code here which is not related to the problem 

     #In this if-statement I check if it does not match with re.search 
     #I assume a for-loop should be here? but not sure how to implement it. 
     if not re.search(r'(.*)XYZname_{0}\(\)\) = .*;(.*)'.format(x+1), my_file_contents): 
      raise Exception("The name: XYZname_{0} was not found".format(x+1) + " in " + filename) 

Hier können die Namen sagen wir zuvor so gesehen werden in eine Datei geschrieben (sie falsch sind)

XYZnameHE_1

XYZnameGJ_2

XYZnameAsd_3

Dann sollte mein Skript sagen Ich kann XYZname_1,2 und 3 in der angegebenen Datei nicht finden.

Natürlich könnte es auch andere Namen geben, für die eine andere Funktion zuständig ist. Diese Namen können mit XXXname_1,2 3 usw. beginnen und wenn einer von ihnen fehlt, ich sollte eine Ausnahme für diese eine ebenso

Im Moment bekomme ich bekommen diese Ausgabe:

Exception: The name: XYZname_1 was not found in C:\Path 

Aber ich möchte etwas wie dieses:

Exception: The name: XYZname_1 was not found in C:\Path 
Exception: The name: XYZname_2 was not found in C:\Path 
Exception: The name: XYZname_3 was not found in C:\Path 
Exception: The name: XXXname_2 was not found in C:\Path 

Weiß nicht, was die "beste Praxis" für das Lösen dieses ist. Eine Möglichkeit besteht darin, das Skript die gesamte Datei durchsehen zu lassen und dann "abstürzen" zu lassen. Oder "crash"/raise direkt, wenn ein Problem gefunden wird? Weil es für den Entwickler lästig wäre, das Skript mehrmals auszuführen, um alle falschen/falschen Namen zu finden.

+1

Warum nicht die fehlenden Namen in einer Liste speichern und dann am Ende erhöhen, wenn die Liste irgendwelche Elemente enthält? –

Antwort

1

Sammeln Sie die Namen/Übereinstimmungen in einer Liste. Dann nach der Schleife eine Ausnahme auslösen, falls erforderlich. Sie brauchen auch findall() anstelle von search() von dem, was ich verstehe.

Am Ende man so etwas haben würde:

matches = [] 
for x in range(0, 3): 
    #Some code here which is not related to the problem 

    # add the matches to the list 
    matches.extend(re.findall(r'(?:.*)(XYZname_{0})\(\)\) = .*;(?:.*)'.format(x+1), my_file_contents)) 

if matches: 
    for match in matches: 
     print("The name: {0} was not found in {1}".format(match, filename)) 
    raise Exception(...) 

Ich habe ersetzt auch die () mit (?:) in Ihrem Ausdruck - ersetzt einfangenden Gruppen mit nicht-Capturing. Auch () um XYZname_{0} hinzugefügt, um den Namen zu erfassen.

+0

Hmm Ich habe das ausprobiert, aber mein Test ist so grün, obwohl die Namen falsch sind. – gants

+0

@gants könnte ein Problem mit dem Ausdruck sein.Ich denke, Sie müssen die Flags 're.DOTALL' und' re.MULTILINE' verwenden. Und Sie können die '(?:. *)' Teile am Anfang und am Ende des Musters vermeiden. – alecxe

+0

Mag es das? 'matchs.extend (re.findall (r '(?:. *) (XYZname_ {0}) \ (\) \) =. *; (?:. *)'. Format (x + 1), meine_Datei_Inhalt) Wenn ich so etwas hinzufüge, sagt es mir, dass es sich um "unerwarteter Fund" handelt. – gants

0

Verwenden try/catch für jedes Element in der Iteration anstelle einem einzigen Durchlauf:

for x in range(): 
    try: 
     re.search ... 
    except: 
     raise exception ... 

Nicht einen Python-Experte, aber von einer reinen Code/Logik-Perspektive, die den Trick tun soll.

Verwandte Themen