【问题标题】:python 2.x:Conditionally Catching Exceptions (Ignore gracefully cleanup if the file is missing)python 2.x:有条件地捕获异常(如果文件丢失,则忽略优雅清理)
【发布时间】:2019-10-02 04:18:13
【问题描述】:

我有一个脚本可以在共享位置清理超过 14 天的日志。现在这个脚本可以从不同的主机同时运行。在特定情况下,如果两个或多个主机尝试清理同一个文件,只有一个会成功,而所有其他主机都会出现错误“没有这样的文件或目录”。如果文件突然丢失,我如何更新代码以忽略优雅清理。下面是执行清理的部分代码。 count 跟踪删除的文件数。

if os.stat(filename).st_mtime < current_time - 14 * 86400:
    try:
       os.remove(filename)
       count += 1
    except:
       logger.warning("Not able to delete the file %s" % filename)

一种方法是如果文件不存在则“通过”异常,但如果您无法删除该文件,则继续记录警告。如何包含此条件。

【问题讨论】:

  • 我想os.stat() 会引发异常?如果是这样,你可以把它移到 try-except 中。或者,您可以使用 os.path.exists 预先检查文件是否存在。
  • @Mark 如果两个主机通过 if 循环该文件存在并且都试图删除它?
  • 是的,这很好。所以最好的做法是使用 try-except 捕获异常。

标签: python exception python-2.x


【解决方案1】:

正如@Mark 建议的那样,您可以事先检查文件是否存在,然后将其删除,但这种方法仍然存在潜在的竞争条件。它可能发生在os.stat 之后和os.remove 之前的脚本实例之间。将所有代码引发错误移至try / except 应该可以完成这项工作。但是,据我了解,记录真实消息存在问题。附加标志 attempted_delete 应该有助于解决这个问题:

attempted_delete = False
try:
    if os.stat(filename).st_mtime < current_time - 14 * 86400:
         os.remove(filename)
         count += 1
         attempted_delete = True
except:
     if attempted_delete:
         logger.warning("Not able to delete the file %s" % filename)

【讨论】:

  • 如果两台主机同时检查会失败,都会发现文件存在但都不能删除。
  • @Rishi Bansal:我相信这正是我写的。
【解决方案2】:

一个没有异常(类型)列表的except 子句是一个包罗万象的:易于设置但难以使用。在这里,您应该专门捕获(并忽略)FileNotFoundError 并记录任何其他异常:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except FileNotFoundError:
   pass  # file has already been deleted: all is fine
except:
   logger.warning("Not able to delete the file %s" % filename)

以上是针对 Python 3 的,当你使用 Python 2 时,你只能检查 OSError,然后控制它的 errno 属性:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except OSError as e:
   if e.errno != errno.ENOENT:
      # do not log if file has already been deleted
      logger.warning("Not able to delete the file %s" % filename)
except:
   logger.warning("Not able to delete the file %s" % filename)

【讨论】:

  • 你能不能给出一个工作代码,它给出的错误“NameError: name 'FileNotFoundError' is not defined”。
  • @RishiBansal:我帮不了你。 FileNotFoundError 是一个内置异常,是OSError 的子类。很奇怪你得到"NameError: name 'FileNotFoundError' is not defined"。你的操作系统和 Python 版本是什么?
  • @serve Python 2.6.6,redhat 6。如果我使用 OSError,它会同时捕获条件文件不存在以及权限不存在。
  • 根据reddit post,这是我在谷歌搜索您的错误时发现的第一件事,FileNotFoundError 仅在 Python3 上。您可以改用 IOError,或运行 Python3。 This SO question 提到了可能适用于 Python 2 和 3 的其他方式。
  • @RishiBansal:在 Python 2 中也可以,请参阅我的编辑。
猜你喜欢
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-13
  • 2023-03-06
相关资源
最近更新 更多