Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Exception 返回异常实例而不是在Python中引发异常实例有什么缺点?_Exception_Python - Fatal编程技术网

Exception 返回异常实例而不是在Python中引发异常实例有什么缺点?

Exception 返回异常实例而不是在Python中引发异常实例有什么缺点?,exception,python,Exception,Python,我一直在使用python couchdb和DesktopCoach进行一些工作。在我提交的一个补丁中,我包装了couchdb的db.update函数。对于任何不熟悉python couchdb的人,函数如下所示: def update(self, documents, **options): """Perform a bulk update or insertion of the given documents using a single HTTP request.

我一直在使用python couchdb和DesktopCoach进行一些工作。在我提交的一个补丁中,我包装了couchdb的
db.update
函数。对于任何不熟悉python couchdb的人,函数如下所示:

def update(self, documents, **options):
    """Perform a bulk update or insertion of the given documents using a
    single HTTP request.

    >>> server = Server('http://localhost:5984/')
    >>> db = server.create('python-tests')
    >>> for doc in db.update([
    ...     Document(type='Person', name='John Doe'),
    ...     Document(type='Person', name='Mary Jane'),
    ...     Document(type='City', name='Gotham City')
    ... ]):
    ...     print repr(doc) #doctest: +ELLIPSIS
    (True, '...', '...')
    (True, '...', '...')
    (True, '...', '...')

    >>> del server['python-tests']

    The return value of this method is a list containing a tuple for every
    element in the `documents` sequence. Each tuple is of the form
    ``(success, docid, rev_or_exc)``, where ``success`` is a boolean
    indicating whether the update succeeded, ``docid`` is the ID of the
    document, and ``rev_or_exc`` is either the new document revision, or
    an exception instance (e.g. `ResourceConflict`) if the update failed.

    If an object in the documents list is not a dictionary, this method
    looks for an ``items()`` method that can be used to convert the object
    to a dictionary. Effectively this means you can also use this method
    with `schema.Document` objects.

    :param documents: a sequence of dictionaries or `Document` objects, or
                      objects providing a ``items()`` method that can be
                      used to convert them to a dictionary
    :return: an iterable over the resulting documents
    :rtype: ``list``

    :since: version 0.2
    """
如您所见,此函数不会引发couchdb服务器引发的异常,而是以元组形式返回它们,其中包含我们要更新的文档的id


其中一位评论员前往irc上的python询问此事。在python中,他们建议使用sentinel值而不是异常。正如你可以想象的那样,仅仅是一种方法是不实用的,因为有很多可能的异常可以被接收。我的问题是,除了使用异常更丑陋之外,使用异常优于哨兵值还有什么缺点?

要提出的异常。它有助于调试、处理错误的原因,并且是其他开发人员的明确和公认的实践

我想从程序的界面上看,不清楚我应该如何处理返回的异常。举起来?从真正导致它的链条之外?这似乎有点复杂


我建议,在成功时返回
docid,new\u rev\u doc
元组,并按原样传播/引发异常。您的方法重复了
success
和第三个返回值的类型。

我认为在这种情况下可以返回异常,因为更新函数的某些部分可能成功,而某些部分可能失败。当您引发异常时,API用户无法控制已经成功的程序。

异常会导致正常程序流中断;然后异常沿着调用堆栈上升,直到被截获为止,否则可能会到达顶部。因此,它们被用来标记一个真正的特殊条件,该条件应由调用方处理。引发异常非常有用,因为如果未满足必要条件,程序将不会继续

在不支持异常的语言(如C)中,您经常被迫检查函数的返回值,以验证一切正常进行;否则程序可能会出现错误

顺便说一下,update()有点不同:

  • 它需要多个参数;有些可能失败,有些可能成功,因此它需要一种方法来传达每个arg的结果
  • 前一个故障与下一个操作无关,例如,它不是永久性错误
在这种情况下,在API中通常不会引发异常。另一方面,如果在执行查询时与数据库的连接断开,那么就应该出现异常(因为这是一个永久性错误,会影响接下来的所有操作)


顺便说一句,如果您的业务逻辑要求所有操作都要成功完成,而您不知道更新失败时该怎么办(即,您的设计说它永远不会发生),请在您自己的代码中随意引发异常。

引发异常是指通知预期工作的某些内容不工作。它破坏了程序流程,只有在程序不知道如何处理的情况下才应该执行

但有时您希望在不中断程序流的情况下发出一点错误标志。您可以通过返回特殊值来实现这一点,这些值很可能是例外

Python在一种情况下在内部实现了这一点。当您比较两个值(如
foo
)时,实际调用是
foo.\uu\lt\uuu(bar)
。若此方法引发异常,程序流将按预期中断。但如果它返回NotImplemented,Python将转而尝试
bar.\uu\ge\uuu(foo)
。因此,在本例中,返回异常而不是引发异常用于标记异常不起作用,但以预期的方式


我认为,这实际上是预期错误和意外错误之间的区别。

简单的“sentinel”优于异常对象的好处是更简单的测试。但是,因为您已经包含了一个成功标志,所以例外是可以的。但是,在同一字段中重载修订/异常似乎不方便。考虑<代码>(DOXYID,ReviOrthOnNo.ExcOrthOnNe)< /Cult>,它允许用户只需要一个案例的详细代码。Beni:你是对的,Rev和Extor的两个单独的字段是一个更好的解决方案。