如何为urlretrieve第三个参数的回调函数添加额外自定义参数
报错原因
你调用Handle_Progress(dlg)的写法会直接触发函数执行,而不是将函数作为回调对象传递给urlretrieve,此时urlretrieve还没有生成blocknum、blocksize、totalsize三个参数,自然会报参数缺失的错误。
解决方法
这里提供三种常用的实现方案,你可以根据自己的代码习惯选择:
方案1:用lambda匿名函数包装(最便捷,适合简单场景)
调用时通过lambda接收urlretrieve传入的三个默认参数,再连同你的自定义参数dlg一起传递给实际的处理函数即可:
# 调用写法 urllib.request.urlretrieve(url, filename, lambda blocknum, blocksize, totalsize: Handle_Progress(dlg, blocknum, blocksize, totalsize)) # 函数定义保持你修改后的写法即可 def Handle_Progress(dlg, blocknum, blocksize, totalsize): # 原有业务逻辑
方案2:用functools.partial偏函数绑定参数(代码最简洁)
偏函数可以提前将固定参数绑定到目标函数上,剩余参数会在回调触发时自动补全:
# 先导入依赖 from functools import partial # 调用写法 urllib.request.urlretrieve(url, filename, partial(Handle_Progress, dlg)) # 函数定义和上面一致即可 def Handle_Progress(dlg, blocknum, blocksize, totalsize): # 原有业务逻辑
方案3:用闭包封装逻辑(适合回调逻辑复杂的场景)
通过外层函数接收自定义参数,返回内层的实际回调函数,内层函数可以直接访问外层传入的dlg变量:
# 定义闭包 def create_progress_handler(dlg): def handle_progress(blocknum, blocksize, totalsize): # 这里可以直接使用dlg变量,不需要作为参数声明 # 原有进度计算、更新dlg的逻辑写在这里 return handle_progress # 调用写法 urllib.request.urlretrieve(url, filename, create_progress_handler(dlg))
内容的提问来源于stack exchange,提问作者yem
相关产品推荐
相关产品推荐

