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
但未经限定的catchBleTestFail
。未经限定的名称可用吗?您确定该类只声明了一次吗?您真的在调用该函数吗?如果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
但是没有限定的catchBleTestFail
。不限定的名称可用吗?你确定该类只声明了一次吗?你真的在调用函数吗?Iffunc
是一个函数,那么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。