5

我没有接受过非常全面的python培训,有时不知道正确的做事方式。其中一件事是测试我的 resultQuery 是否返回结果。我发现自己经常这样做:

    try:
        user = User.objects.get(email=email)
    except DoesNotExist:
        user = User()

我不了解python,但其他语言的尝试捕获应该是用于异常而不是用于正常程序流。如果其他情况,您将如何做到这一点?我想我想要类似的东西:

if request.GET.get('email','') is not None:
    email = request.GET['email'])
4

4 回答 4

4

您的异常示例通常是做事的首选方式。维基百科对此有很好的描述:

每当出现错误情况时,Python 风格都要求使用异常。与其在实际使用文件或资源之前测试对它的访问,Python 中的传统做法是继续尝试使用它,如果访问被拒绝,则捕获异常。

异常通常用作 if-block (...) 的替代方法。一个常用的座右铭是 EAFP,即“请求宽恕比许可更容易”。

Python 中的异常不一定代价高昂。再次引用维基百科的例子:

if hasattr(spam, 'eggs'):
    ham = spam.eggs
else:
    handle_error()

... 相对:

try:
    ham = spam.eggs
except AttributeError:
    handle_error()

这两个代码示例具有相同的效果,尽管会有性能差异。当垃圾邮件具有鸡蛋属性时,EAFP 样本将运行得更快。当垃圾邮件没有鸡蛋属性时(“例外”情况),EAFP 样本将运行得更慢。

特别是对于 Django,我会使用异常示例。这是在该框架中做事的标准方式,遵循标准绝不是一件坏事:)。

于 2013-09-07T18:28:33.343 回答
0

您可以使用.filter()代替.get(),也可以使用 django 的优化查询集评估。

你可以做

qs = User.objects.filter(email=email)
if qs :
    user = qs[0]
...
于 2013-09-07T18:28:00.987 回答
0

当需要严格测试时, Django 定义了一个EmptyQuerySet可用于特殊实现的类。isinstance(...)

一个简单的方法如下:

try:
    user = User.objects.get(email=email)
    if  user:
        # ...
    else:
        # ...

except DoesNotExist:
    user = User()

Django 提供了get一种直接检索单个模型实例或将引发异常的方法。在这种情况下,正常的方法是检查异常,例如DoesNotExist

要像往常一样从数据库查询中检索整个行,请使用该user.objects.filter(...)方法。返回的QuerySet实例为您提供.count(),.exists()方法。

于 2013-09-07T18:39:58.853 回答
0

我同意捕获异常是这里的正常模式。如果您确实需要检查查询集是否返回结果,该exists方法是一种我认为尚未提及的方法。文档贯穿了各种性能影响,最值得注意的是,如果您知道查询集将被评估,最好只检查查询集的布尔解释。

于 2013-09-07T18:41:23.983 回答