2016-11-03 4 views
0

Ich sende Anforderungen an einen Server und empfange Antworten. Abhängig von der Situation variieren die Antworten und ich muss jeden von ihnen unterschiedlich behandeln.Verschiedene Serverantworten elegant behandeln

Was würde ich tun gerne etwas dieser Art haben:

if response.getChild('child1')... == x: 
    do_math() 
    return stuff1 
elif response.getChild('child2')... == y 
    do_different_math() 
    return stuff2 
etc... 

Allerdings habe ich in das Problem bin mit, dass verschiedene Kinder existieren möglicherweise nicht, das macht mich mehrere try-except verwenden Flusskontrollen. Dies nimmt viel Platz und ist furchtbar hässlich:

try: 
    if response.getChild('child1')... == x: 
     do_math() 
     return message1 
except: 
    return generic_error_message 
try: 
    if response.getChild('child2')... == y: 
     do_different_math() 
     return stuff2 
except: 
    return generic_error_message 
etc... 

Gibt es eine elegante Art und Weise verschiedene mögliche Antworten zu behandeln?

+0

Der [ 'get'] (https://docs.python.org/2/library/stdtypes.html#dict.get) Methode aus Python-Wörterbüchern hat ein interessantes Verhalten, um einen Standardwert bereitzustellen, wenn der erwartete Wert nicht gefunden wird. Sehen Sie sich die Dokumentation der getChild-Methode an und prüfen Sie, ob es sich um ein [Mapping] (https://docs.python.org/3/glossary.html#term-mapping) Objekt handelt. Wenn ja, können Sie einen Ansatz wie 'response.getChild ('child2', None)' verwenden und mit 'None'result umgehen. –

Antwort

0

Lassen Sie mich empfehlen, dass Sie Ihre Bedenken trennen. Sie wollen effektiv:

  • eine Antwort erhalten, die

Der Prozess eine Antwort bekommen kann dazu führen, eine Ausnahme von

  • eine Operation durchführen, basierend auf dem Wert der Reaktion eine Ausnahme auslösen kann erhoben werden, weil das Kind, nach dem du suchst, möglicherweise nicht existiert. Ihr Code fängt alle Ausnahmen ab, Sie sollten versuchen, eine bestimmte Ausnahme abzufangen. Wenn das Kind nicht existiert, müssen Sie keine Operation ausführen. Ich würde so etwas wie empfehlen:

    # define a function to return the right 
    # operation to perform based on response 
    # obviously the methods do_math and do_different_math must be defined 
    # as well as x and y 
    def what_to_do(val): 
        if val == x: 
         return do_math 
        elif val == y: 
         return do_different_math 
        else: 
         raise ValueError("Unknown value %r. I don't know what to do" % val) 
    
    # Do something to get the node that you want 
    # here is just set the value to 'child1' for 
    # demonstration purposes 
    node = 'child1' 
    result = None 
    answer = None 
    
    try: 
        result = response.getChild(node) 
    except SOMES_SPECIFIC_EXCEPTION: 
        # you need to decide what to do here 
        pass 
    
    if result is not None: 
        operation = what_to_do(result) 
        answer = operation() 
    return answer 
    

    HINWEIS Da Sie mehrere Knoten durchlaufen müssen (Kinder). Sie können den Code in eine for-Schleife einfügen.

  • +0

    Der Teil "Tun Sie etwas, um den Knoten, den Sie wollen" ist genau das Problem, das macht mich multiplizieren "versuchen: außer:" Segmente Idealerweise würde ich nur einen Versuch wollen: außer Block, der den Fall behandelt, wenn ich bekomme keine Antwort. In allen anderen Fällen überprüfe ich nur, ob es einen bestimmten Knoten gibt, den ich mit einer if-Anweisung machen möchte, aber nicht, weil das Fehlen davon einen Fehler auslöst, anstatt nur zur nächsten Klausel überzugehen. – JohnnyQ

    0

    Sie haben nicht genug Kontext für eine genauere Antwort geben (wie das, was response und response.getChild() sind, welche Ausnahme (n) getChild() könnte erhöhen und wie sie wirklich behandelt werden sollen). Auch Sie scheinen verschiedene Bedenken zu mischen - die Verarbeitung nach bestimmten Bedingungen zu versenden und Nachrichten an den Benutzer auszugeben.

    Wie dem auch sei: Ein Weg, hässlich wiederholt/Code zu vermeiden, ist eine Folge von Objekten sowohl den Test und die Verarbeitung und dann die Schleife über dieser Sequenz, also Einkapselung zu bauen:

    class Action(object): 
        def __init__(self, accept, run, message): 
         self.accept = accept 
         self.run = run 
         self.message = message 
    
    
    actions = [ 
        Action(lambda r: r.getChild("child1") == x, do_math, some_message), 
        Action(lambda r: r.getChild("child2") == y, do_different_math, some_other_message), 
        ] 
    
    def dispatch(response, actions): 
        for action in actions: 
         try: 
          if action.accept(response): 
           action.run() 
           return action.message 
         except SomeExpectedException as e: 
          return generic_error_message 
    
    Verwandte Themen