英文:
How to return a value from onerror callback in shutil.rmtree
问题
你可以将log
字典作为_error_log
函数的参数传递,并在函数内部进行更新。这样,当函数执行完毕后,你就可以直接返回更新后的log
字典了。以下是修改后的代码示例:
def _error_log(log, func, path, excinfo):
"""
Function that track and record the errors when removing files/dirs
Args:
log (dict): The dictionary to store the error log.
func (function): The function that raised the error.
path (string): Path to the file/dir that raised the error.
excinfo (tuple): The exception information returned by sys.exc_info().
"""
# Set the file/dir full path as key with an empty list as value
log.setdefault(path, [])
# Append the error class and message raised from excinfo tuple
log[path].append(excinfo[0].__name__)
log[path].append(excinfo[1].strerror)
# Append the function that raised the error
log[path].append(func.__name__)
# Import
import shutil
# Path to the directory to remove
path_to_remove = r"C:\shutil_test\remove_me"
log = {}
shutil.rmtree(path_to_remove, onerror=lambda func, path, excinfo: _error_log(log, func, path, excinfo))
# Now you can use the 'log' dictionary outside the function
print(log)
在修改后的代码中,我们将log
字典作为参数传递给_error_log
函数,并在函数内部进行更新。在调用shutil.rmtree
时,我们使用了一个lambda函数来调用_error_log
函数,并将log
字典作为参数传递进去。这样,在_error_log
函数内部对log
字典的更新就会反映在外部的log
变量上。最后,你可以在函数外部使用log
字典来获取错误日志信息。
英文:
Working with rmtree
from shutil
module, I made some tests to delete some directories and their content, knowing that rmtree
takes a callback function on onerror
argument, I created a function to keep track of the errors raised, code as below:
def _error_log(func, path, excinfo):
"""
Function that track and record the errors when removing files/dirs
Args:
func (function): The function that raised the error.
path (string): Path to the file/dir that raised the error.
excinfo (tuple): The exception information returned by sys.exc_info().
"""
# Log dict -> key= file/dir fullpath: value= [error class, error message, function that raised the error]
log = {}
# Set the file/dir full path as key with an empty list as value
log.setdefault(path, [])
# Append the error class and message raised from excinfo tuple
log[path].append(excinfo[0].__name__)
log[path].append(excinfo[1].strerror)
# Append the function that raised the error
log[path].append(func.__name__)
return log
# Import
import shutil
# Path to the directory to remove
path_to_remove = r"C:\shutil_test\remove_me"
shutil.rmtree(path_to_remove, onerror=_error_log)
How can I return the log
dict from _error_log
function ? I thought about using a global variable, but it is kind of messy.
答案1
得分: 1
我相信最简洁的方法是创建一个类,并将日志存储为实例的属性。以下是使用你的原始函数进行最小实现的示例:
class RmtreeErrorLogger:
def __init__(self):
# 日志字典 -> 键=文件/目录完整路径,值= [错误类,错误消息,引发错误的函数]
self.log = {}
def logger(self, func, path, excinfo):
# 将文件/目录完整路径设置为键,值为空列表
self.log.setdefault(path, [])
# 将从excinfo元组中引发的错误类和消息追加到列表中
self.log[path].append(excinfo[0].__name__)
self.log[path].append(excinfo[1].strerror)
# 追加引发错误的函数
self.log[path].append(func.__name__)
使用方法如下:
import shutil
# 要删除的目录路径
path_to_remove = r"C:\shutil_test\remove_me"
logger = RmtreeErrorLogger()
shutil.rmtree(path_to_remove, onerror=logger.logger)
# 例如,检查是否有任何错误:
if logger.log:
print('发生错误')
你可以使用可调用的类来避免使用logger.logger
这样的语法。
英文:
I believe the cleanest way is to create a class and store your log as an attribute of the instance. A minimal implementation using your original function:
class RmtreeErrorLogger:
def __init__(self):
# Log dict -> key= file/dir fullpath: value= [error class, error message, function that raised the error]
self.log = {}
def logger(self, func, path, excinfo):
# Set the file/dir full path as key with an empty list as value
self.log.setdefault(path, [])
# Append the error class and message raised from excinfo tuple
self.log[path].append(excinfo[0].__name__)
self.log[path].append(excinfo[1].strerror)
# Append the function that raised the error
self.log[path].append(func.__name__)
To use it:
import shutil
# Path to the directory to remove
path_to_remove = r"C:\shutil_test\remove_me"
logger = RmtreeErrorLogger()
shutil.rmtree(path_to_remove, onerror=logger.logger)
# For example, check if there is any error:
if logger.log:
print('Errors happened')
You could use a callable class to avoid having to say logger.logger
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论