如何在Python中正确使用try/except

7
我有一个可以返回MongoDB数据库连接处理程序的函数。我有其他一些需要调用该数据库的函数,所以我想把连接处理程序放到一个函数中,这样我不必在每个函数中定义它。
看起来这样做没问题吗?我的问题是,如果无法连接到数据库服务器,它将同时打印两条消息"Could not connect to server"和"No hosts found"。我该如何只打印"Could not connect to the server"呢?
def mongodb_conn():
    try:
        conn = pymongo.MongoClient()
    except pymongo.errors.ConnectionFailure, e:
        print "Could not connect to server: %s" % e
    return conn

def get_hosts()
    try:
        conn = mongodb_conn()
        mongodb = conn.dbname.collection

        b = []
        hosts_obj = mongodb.find({'_id': 'PR'})
        for x in hosts_obj:
            print x
    except:
        print "No hosts found"

get_hosts()

mongodb_conn 中可能会出现错误:如果发生异常,conn 将永远未被定义! - ForceBru
也许是 except: pass - ρss
1
@pss 哎呀,不要推荐那个,那真的太糟糕了。 - Daniel Roseman
2个回答

14

将你的conn = mongodb_conn()调用从try .. except处理程序中移出,并测试是否返回None

def get_hosts()
    conn = mongodb_conn()
    if conn is None:
        # no connection, exit early
        return

    try:
        mongodb = conn.dbname.collection

        b = []
        hosts_obj = mongodb.find({'_id': 'PR'})
        for x in hosts_obj:
            print x
    except:
        print "No hosts found"

你应该不惜一切代价避免使用一个笼统的 except 语句;现在你捕获了所有异常,包括内存错误和键盘中断,参见为什么“ except: pass ”是一种糟糕的编程实践?

只使用特定的异常类型;你可以使用一个 except 语句来捕获多个异常类型:

except (AttributeError, pymongo.errors.OperationFailure):

你可以使用多个 except 语句来处理不同方式的异常。

将异常处理器限制在可能抛出异常的代码部分。例如,for x in hosts_obj: 循环可能不会抛出 AttributeError 异常,因此它可能不应该是 try 块的一部分。

请注意,您需要调整 mongodb_conn() 函数,以便在未设置 conn 本地变量时不尝试使用它;如果这样做,您将会收到一个 UnboundLocal 错误:

def mongodb_conn():
    try:
        return pymongo.MongoClient()
    except pymongo.errors.ConnectionFailure, e:
        print "Could not connect to server: %s" % e

现在,如果连接成功,该函数返回连接,如果连接失败,则返回 None


@PadraicCunningham:什么会引起连接错误? - Martijn Pieters
我没有意识到你改变了代码,但现在你捕获了所有异常,而不是原始代码中的内容,对吗? - Padraic Cunningham
@PadraicCunningham:原始代码捕获所有异常。这就是问题所在。 - Martijn Pieters
不按预期工作...例如,对于无效的连接字符串,不会发生ConnectionFailure异常。更喜欢@Pallav的答案。 - Eduardo Lucio
@EduardoLucio:如果你这么说,那我只是从问题中摘取了这一点。我的回答讨论的是如何处理连接失败,而不是如何最好地检测它们。 - Martijn Pieters

1
您还可以像这样检查服务器是否可用:

        from pymongo.errors import ConnectionFailure
        client = MongoClient()
        try:
            # The ismaster command is cheap and does not require auth.
            client.admin.command('ismaster')
        except ConnectionFailure:
            print("Server not available")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接