如何在python中生成返回与原始 predicate 相反的可调用 predicate

5jvtdoz2  于 2021-08-20  发布在  Java
关注(0)|答案(2)|浏览(242)

在google.api_core.retry包中,有一个名为 if_exception_type() 此函数创建一个 predicate 来检查异常是否属于给定类型。下面是它的源代码。

def if_exception_type(*exception_types):
    """Creates a predicate to check if the exception is of a given type.

    Args:
        exception_types (Sequence[:func:`type`]): The exception types to check
            for.

    Returns:
        Callable[Exception]: A predicate that returns True if the provided
            exception is of the given type(s).
    """

    def if_exception_type_predicate(exception):
        """Bound predicate for checking an exception type."""
        return isinstance(exception, exception_types)

    return if_exception_type_predicate

现在,我正在使用GoogleBigQueryReservationAPI,并希望删除bq保留(如果存在)。我有一些这样的代码。

from google.cloud.bigquery_reservation_v1 \
    import ReservationServiceClient, CapacityCommitment, Reservation, Assignment
from google.api_core.retry import Retry, if_exception_type
from google.api_core import exceptions as gcp_exceptions

bq_resrv_api = ReservationServiceClient()
bq_resrv_api_retry = Retry(deadline=120,
                            predicate=if_exception_type_not(gcp_exceptions.NotFound),
                            maximum=3)

try:
    bq_resrv_api.delete_reservation(
        name=reservation_registry["reservation_id"],
        retry=bq_resrv_api_retry
    )
    print("BQ slot reservation deleted: {}".format(reservation_registry["reservation_id"]))
except gcp_exceptions.NotFound:
    print("BQ slot reservation not found, skip deletion: {}".format(reservation_registry["reservation_id"]))

如何创建函数 if_exception_type_not() 这将创建一个 predicate 来检查异常是否不是给定的类型?(相反的 if_exception_type() )
我想出了一个答案(我将在下面发布),但是,我认为应该有一个更好/更优雅/更通用的方法来做。

o75abkj4

o75abkj41#

这是实现if_exception_type_not()函数的一种方法。

def if_exception_type_not(*exception_types):
    # get the predicate func from if_exception_type
    if_exception_type_predicate = if_exception_type(*exception_types)
    # define a new predicate func that returns the opposite
    def if_exception_type_predicate_not(exception):
        return not if_exception_type_predicate(exception)
    # return the new predicate func
    return if_exception_type_predicate_not

但是,正如您所看到的,它非常特定于 if_exception_type() . 我认为必须有一种更通用的方法来做到这一点。

n1bvdmb6

n1bvdmb62#

你可以做一个 Package 纸 not 函数,并调用它 invert 或类似的。
我们希望得到一个带有签名的函数 exception -> bool .
我们已经可以访问一个函数 exception -> bool ,因此我们只需要将其与一个函数链接,该函数可以接受一个函数并返回一个新函数,其结果是相反的: (exception -> bool) -> (exception -> bool) . 这只是一个装饰师。

from functools import wraps

def invert(func):
    @wraps(func)
    def wrapper(*args,**kwargs):
        return not func(*args,**kwargs)
    return wrapper

那你就可以通过了

predicate=invert(if_exception_type(gcp_exceptions.NotFound))

相关问题