优雅地处理不同的服务器响应

时间:2016-11-03 11:07:45

标签: python xml soap

我将请求发送到服务器并接收响应。根据具体情况,反应各不相同,我必须以不同的方式处理每一种。

我想做的是拥有这样的东西:

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

但是,我遇到的问题是不同的孩子可能不存在,这使我不得不使用多个try-except流控制。这需要很大的空间并且非常难看:

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...

是否有一种优雅的方式来处理不同的可能反应?

2 个答案:

答案 0 :(得分:0)

我建议您分开您的疑虑。你实际上想要:

  • 得到回复,可能会引发异常
  • 根据回复的值执行操作

获取响应的过程可能会导致异常,因为您正在寻找的孩子可能不存在。您的代码捕获所有异常,您应该尝试捕获特定的异常。如果孩子不存在,您不需要尝试执行任何操作。我建议像:

# 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

注意因为您需要迭代多个节点(子节点)。您可以将代码放在for循环中。

答案 1 :(得分:0)

您没有提供足够的背景信息来获得更准确的答案(例如responseresponse.getChild()getChild()可能引发的例外情况以及它们的真实情况应该被处理)。此外,您似乎正在混合两个不同的问题 - 根据某些条件调度处理并向用户发出消息。

无论如何:避免丑陋重复/代码的一种方法是构建一个封装测试和处理的对象序列,然后遍历这个序列,即:

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