Python 当函数转换为lambda并在另一个函数中执行时,未捕获异常

Python 当函数转换为lambda并在另一个函数中执行时,未捕获异常,python,python-3.x,Python,Python 3.x,如您所见,connect函数通过convert将\u connect函数转换为lambda,并将其传递给run\u api函数。在\u connect中引发的异常不会被捕获,除非在run\u api函数中。对于lambda,是否需要执行任何操作 代码看起来不错,但仍然无法理解为什么在出现故障时无法捕获异常 这是我的密码 def run_api(function, retry_count): count = 0 while count < retry_count:

如您所见,
connect
函数通过
convert
\u connect
函数转换为lambda,并将其传递给
run\u api
函数。在
\u connect
中引发的异常不会被捕获,除非在
run\u api
函数中。对于
lambda
,是否需要执行任何操作

代码看起来不错,但仍然无法理解为什么在出现故障时无法捕获异常

这是我的密码

def run_api(function, retry_count):
    count = 0
    while count < retry_count:
        count += 1
        try:
            function()
            return True
        except (BleTestFail, BleTestError):
            if count == retry_count:
                return False


def convert(func):
    return lambda: func


def _connect(self, target_id):
    result = self.device.ble_central.connect(target_id)
    self.logger.debug('Connect output %s', result)

    if result['op'] != 'ok':
        self.logger.error('Connect command execution failed')
        raise ble_utils.BleTestFail('Failed to connect')

    return True

def connect(self, target_ids, retry_count=1):
    connected = []
    unconnected = []
    if not isinstance(target_ids, list):
        target_ids = [target_ids]
    for target_id in target_ids:
        connect_function = ble_utils.convert(self._connect(target_id))
        connect_status = ble_utils.run_api(connect_function, retry_count,
                                           'connecting device %s' % target_id,
                                           self.logger)
        if connect_status:
            connected.append(target_id)
        else:
            unconnected.append(target_id)

    if connected:
        self.logger.info('Connected to %s devices: %s', len(connected), connected)
    if unconnected:
        self.logger.error('Unable to connect %s devices: %s', len(unconnected),
                          unconnected)
    return connected, unconnected
def run_api(函数,重试计数):
计数=0
计数<重试\计数时:
计数+=1
尝试:
函数()
返回真值
除了(BLETESTFILE,BLETESERROR):
如果计数==重试计数:
返回错误
def转换(func):
返回lambda:func
def_连接(自身、目标id):
结果=self.device.ble\u central.connect(目标id)
self.logger.debug('连接输出%s',结果)
如果结果['op']!='好的:
self.logger.error('连接命令执行失败')
raise ble_utils.BLETESTFILE('连接失败')
返回真值
def connect(自身、目标\u ID、重试\u计数=1):
已连接=[]
未连接=[]
如果不存在(目标ID,列表):
target_id=[target_id]
对于目标\u id中的目标\u id:
connect\U function=ble\U utils.convert(自我连接(目标id))
connect\u status=ble\u utils.运行\u api(connect\u函数,重试\u计数,
'正在连接设备%s'%1!''目标\u id,
自动记录器)
如果连接状态为:
已连接。追加(目标\u id)
其他:
未连接。追加(目标\u id)
如果已连接:
self.logger.info('连接到%s设备:%s',len(已连接),已连接)
如果未连接:
self.logger.error('无法连接%s设备:%s',len(未连接),
未连接)
返回已连接,未连接

因此,为了澄清,我们有一个示例“API”,我们希望为其提供回调:

因此,现在我们想调用
运行带有
连接的api
。\u connect
,但以某种方式提供
目标id
信息

这称为绑定,最优雅的方法是使用标准库
functools.partial

from functools import partial

# This is how we can make the `convert` function from before:
def convert(func, param):
    return partial(func, param)
# But there is no point to this, since we can just use `partial` directly.
# There was no hope for the original approach, because you were calling the 
# function ahead of time and passing the returned result to `convert`.

# So, the process looks like this:
# target_id = 1, retry_count = 2
run_api(partial(connection._connect, 1), 2)
您可以使用
lambda
,但我不推荐使用它-
functools。partial
更明确,并且可以优雅地处理具有一些意外缺陷的更高级用例(特别是,如果您想在一个循环中进行多个回调,您可能会发现它们都意外地绑定到同一个值,或者您必须使用非常难看的解决方法)。但为了完成,看起来是这样的:

def convert(func, param):
    return lambda: func(param)

因此,为了澄清,我们有一个示例“API”,我们希望为其提供回调:

因此,现在我们想调用
运行带有
连接的api
。\u connect
,但以某种方式提供
目标id
信息

这称为绑定,最优雅的方法是使用标准库
functools.partial

from functools import partial

# This is how we can make the `convert` function from before:
def convert(func, param):
    return partial(func, param)
# But there is no point to this, since we can just use `partial` directly.
# There was no hope for the original approach, because you were calling the 
# function ahead of time and passing the returned result to `convert`.

# So, the process looks like this:
# target_id = 1, retry_count = 2
run_api(partial(connection._connect, 1), 2)
您可以使用
lambda
,但我不推荐使用它-
functools。partial
更明确,并且可以优雅地处理具有一些意外缺陷的更高级用例(特别是,如果您想在一个循环中进行多个回调,您可能会发现它们都意外地绑定到同一个值,或者您必须使用非常难看的解决方法)。但为了完成,看起来是这样的:

def convert(func, param):
    return lambda: func(param)

您提出了
ble_utils.BleTestFail
但未经限定的catch
BleTestFail
。未经限定的名称可用吗?您确定该类只声明了一次吗?您真的在调用该函数吗?如果
func
是一个函数,则
lambda:func
只返回该函数而不调用它。您可能需要
lambda:func()
ble\u utils.convert(self.\u connect(target\u id))
无法真正将其转换为lambda,您传递的是
\u connect
的返回值,而不是函数。
ble_utils.convert
convert
有什么关系?我不理解整个函数到lambda的事情。您有一个函数返回函数,因此要调用它,您必须执行
func()()
@Sraw是的,我可能传递的是返回值,而不是要转换的函数。我现在应该尝试什么呢?你提出了
bleuutils.BleTestFail
但是没有限定的catch
BleTestFail
。不限定的名称可用吗?你确定该类只声明了一次吗?你真的在调用函数吗?If
func
是一个函数,那么
lambda:func
只返回此函数而不调用它。您可能需要
lambda:func()
ble\u utils.convert(self.\u connect(target\u id))
无法真正将其转换为lambda,您传递的是
\u connect
的返回值,而不是函数。
ble_utils.convert
convert
有什么关系?我不理解整个函数到lambda的事情。您有一个函数返回函数,因此要调用它,您必须执行
func()()
@Sraw是的,我可能传递的是返回值,而不是要转换的函数。我现在应该尝试什么呢谢谢你的时间,我将使用partial。谢谢你的时间,我将使用partial。