try语句的可选else子句的预期用途是什么?


当前回答

我发现它非常有用,当你有清理工作要做,即使有例外:

try:
    data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
    handle_exception(e)
else:
    do_stuff(data)
finally:
    clean_up()

其他回答

就是这样。try-except子句中的'else'块用于当(且仅当)被试操作成功时运行的代码。它可以被利用,也可以被滥用。

try:
    fp= open("configuration_file", "rb")
except EnvironmentError:
    confdata= '' # it's ok if the file can't be opened
else:
    confdata= fp.read()
    fp.close()

# your code continues here
# working with (possibly empty) confdata

就我个人而言,我喜欢它,并在适当的时候使用它。它在语义上对语句进行分组。

else:块令人困惑并且(几乎)毫无用处。它也是for和while语句的一部分。

实际上,即使在if语句中,else:也可能被滥用,造成非常难以发现的错误。

考虑这一点。

   if a < 10:
       # condition stated explicitly
   elif a > 10 and b < 10:
       # condition confusing but at least explicit
   else:
       # Exactly what is true here?
       # Can be hard to reason out what condition is true

三思而后行。这通常是个问题。除非在if语句中,否则避免使用它,即使在if语句中,也要考虑记录else-条件,使其显式。

下面是我喜欢使用这种模式的另一个地方:

 while data in items:
     try
        data = json.loads(data)
     except ValueError as e:
        log error
     else:
        # work on the `data`

错误和异常#处理异常- docs.python.org

The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example: for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close() The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.

我将添加另一个用例,在处理DB会话时看起来很直接:

    # getting a DB connection 
    conn = db.engine.connect()

    # and binding to a DB session
    session = db.get_session(bind=conn)

    try:
        # we build the query to DB
        q = session.query(MyTable).filter(MyTable.col1 == 'query_val')

        # i.e retrieve one row
        data_set = q.one_or_none()

        # return results
        return [{'col1': data_set.col1, 'col2': data_set.col2, ...}]

    except:
        # here we make sure to rollback the transaction, 
        # handy when we update stuff into DB
        session.rollback()
        raise

    else:
        # when no errors then we can commit DB changes
        session.commit()

    finally:
        # and finally we can close the session
        session.close()