【问题标题】:How to use try, except, else correctly in Python如何在 Python 中正确使用 try、except、else
【发布时间】:2012-11-06 04:25:57
【问题描述】:

所以我想知道编写 try except 语句的正确方法。我是 Python 中错误处理的新手。

选项 1

try:
    itemCode = items["itemCode"]
    dbObject=db.GqlQuery("SELECT * FROM %s WHERE code=:1" % dbName,itemCode).get()
    dbObject.delete() 
except AttributeError:
    print "There's no item with that code"
except KeyError:
    print "Bad parameter name"
except:
    print "Unknow error" 

选项 2

try:
    itemCode = items["itemCode"]
except KeyError:
    print "Bad parameter name"
else:    
    dbObject=db.GqlQuery("SELECT * FROM %s WHERE code=:1" % dbName,itemCode).get()
    try:    
        dbObject.delete() 
    except AttributeError:
        print "There's no item with that code"
    except:
        print "Unknow error" 

选项 3 您能想到的任何其他更好的选择。

选项 1,我们看到我将所有代码包装在一个 try 块中。 选项 2,它使用嵌套块。它在特定行语句上引发异常。

如果某处有错误,我会很高兴知道的。

【问题讨论】:

  • 我不完全理解你的问题。在我看来,你的主要问题是理解 try, except, else, 最终是如何工作的。那是对的吗?如果是这样,我可以提供一个示例来解释这一点。
  • @inspectorG4dget - 我认为问题不在于它们是如何工作的(两个例子都是有效的)和一个风格偏好问题。
  • 我不明白您为什么要删除 try: 块和 else: 块中的对象,是我遗漏了什么还是没有意义?
  • 您可能应该使用if dbObject is not None: dbObject.delete() 而不是在此处捕获 AttributeError。
  • @inspectorG4dget Lattyware 这是关于编码风格的。代码做什么并不重要。 J.F.塞巴斯蒂安。我认为这是另一个主题,关于使用 if vs try 语句

标签: python exception python-2.7


【解决方案1】:

我更喜欢使用带有验证的 dicts 的 get 方法,而不是捕获 KeyError。

itemCode = items.get("itemCode") # itemCode will be None, if no such key
if itemCode is not None:
    print "code missing"

这不是“通用”解决方案(请参阅我的回答中的 cmets),但在这种情况下它会有所帮助。

在第一种情况下,我不明白,你为什么要尝试删除两次。

try:
    itemCode = items.get("itemCode") # itemCode will be None, if no such key
    if itemCode is not None:
        print "code missing"
    dbObject=db.GqlQuery("SELECT * FROM %s WHERE code=:1" % dbName,itemCode).get()
    dbObject.delete() 
except AttributeError:
    print "There's no item with that code"
except StandardError as ex:    # good idea to be prepared to handle various fails
    print "Unexpected error deleting item {}".format(ex)

另外,不要忘记 python 有 finally 部分。它有时会派上用场。

【讨论】:

  • 这不是一个非常 Pythonic 的方法,因为您的代码在 items['itemCode'] 为 0、False、[]、{} 或其他任何评估为 @ 的情况下会失败987654328@。 try/except 在这种情况下更受欢迎,因为它实际上捕获了未找到该项目的特定情况。 if not itemCode 不会产生误报。
  • 是的,我真的很抱歉,这是我的错误(真的很累,并试图快速回答)。当然,is None 和 is not None 应该始终用于检查 value 是否为 None (或不是)。我已经更正了代码。
  • 不道歉。我们都在这里试图一起解决这些问题。 :-) 但即使在新代码中,您也无法区分'itemCode' not in items 和items['itemcode'] is None。 None 是一个完全有效的存储值,None 和 KeyError 之间存在很大差异。
  • 是的,你说得对。最好的方法是检查子键,使用in。我仍然认为在大多数情况下它比排除异常更好。但在很多情况下(还有这个)—— None 是不可接受的值,所以这会起作用。但毫无疑问,您需要了解这样做的风险。
【解决方案2】:

来自python的禅意,“扁平胜于嵌套”。一般来说,我会选择选项#1 样式,尽管我对dbObject=db.GqlQuery("SELECT.... 或dbObject.delete() 是否引发AttributeError 有点困惑。但无论如何,您不必多次致电dbObject.delete()。

【讨论】:

  • 我的错,我修复了双重删除。 dbObject.delete() 引发 AttributeError
  • 捕获所有错误并通过简单的“未知错误”消息隐藏它们并不是一个好主意。当您看到这样的错误消息时,很难理解发生了什么。
  • @cleg 这是我不知道的错误。当他们来的时候我会抓住他们
  • @john.dou.2011 异常处理的想法是,如果你不知道错误以及如何处理它,你让它传播到可能能够并且虽然你'正在打印“未知错误”我认为 cleg 指出它很容易错过,因此可能会发生奇怪的事情......
  • @jonClements 对不起,我不太明白你的概念。也许您可以通过编码示例向我展示或指出正确的方向以供进一步阅读。谢谢
【解决方案3】:

简单 - 视情况而定。如果您确定会遇到什么异常,您可以坚持使用 1),坦率地说,90% 的情况都是如此。如果您知道许多代码例程可以引发相同的异常类型,则第二种方法很有用。

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 2021-03-15
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多