Python try: ing 不要重复代码。尝试:除了和其他

Python try: ing not to repeat code. try: except and else

我有这个:

try:    
    if session.var:
        otherVar = session.var
    else:
        util = db.utility[1]
        otherVar = session.var = util.freshOutTheBank
except AttributeError:
    util = db.utility[1]
    otherVar = session.var = util.freshOutTheBank

...do stuff with otherVar

情况是 session.var 可能不存在或者可能是 None。用户在会话期间也 运行 多次使用此代码。

如何避免重复代码。我基本上想做一个 'except and else' 还是我看错了?

如果 session.var 不存在,您可以避免使用 session.var,方法是首先使用 hasattr 检查它。这避免了对 try/except 块的需要。

if hasattr(session, 'var') and session.var is not None:
    ...
else:
    ...

另一种方法可能是在您的原始代码中让 else 只是 raise 进入 except 块的例外,但这有点丑陋:

try:
    if session.var:
        ...
    else:
        raise AttributeError
except AttributeError:
    ...

在这种情况下,我认为 "Look Before you Leap" 编程风格(使用 hasattr)比 "Easier to Ask Forgiveness than Permission" 通常更加 Pythonic 风格(使用异常作为流程的一部分)更好控制)。但是任何一个都可以。

如果您的代码被分割成更小的函数,处理这个问题可能会更容易。例如,如果您编写了一个 get_session_var 函数,它可以从成功案例(在 tryif 块内)中 return ,并且可以解决两个错误案例后来:

def get_session_var(session):
    try:
        if session.var:
            return session.var
    except AttributeError:
        pass

    util = db.utility[1]
    session.var = util.freshOutTheBank
    return session.var

假设这是一个 web2py session 对象,请注意它是 gluon.Storage 的一个实例,它就像一个字典,但有两个例外:(1) 键可以像属性一样访问,并且(2) 访问不存在的 key/property returns None 而不是引发异常。因此,您可以简单地执行以下操作:

otherVar = session.var = session.var if session.var else db.utility[1].freshOutTheBank

注意,如果要区分不存在的键和显式值为 None 的键,则不能使用 hasattr(session, 'var'),因为那样会 return True 即使没有 'var' 键。相反,您可以检查 session.has_key('var'),如果没有 'var' 键,它将 return False