【问题标题】:Why is code inside an if statement running when the condition is false?当条件为假时,为什么 if 语句中的代码会运行?
【发布时间】:2020-12-10 03:00:18
【问题描述】:

我有一个 if 语句检查目录是否已经存在:

if not os.path.exists(os.path.dirname(save_to)):
     os.makedirs(os.path.dirname(save_to))

在此之后,文件被添加到目录save_to,无论它以前是否存在。

有时,即使目录已经存在,if 语句中的代码也会执行。这完全是随机的。

我相信这是因为我正在使用multiprocessing.Pool.map 将此任务分配给多个 CPU。我认为过程 1 和 2 进入 if 语句。我认为进程 1 然后创建目录,然后进程 2 尝试并失败。

这是我得到的错误:

multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
  File "/home/WNeill/anaconda3/lib/python3.8/multiprocessing/pool.py", line 125, in worker
    result = (True, func(*args, **kwds))
  File "/home/WNeill/anaconda3/lib/python3.8/multiprocessing/pool.py", line 51, in starmapstar
    return list(itertools.starmap(args[0], args[1]))
  File "/home/WNeill/who-said-what/wsw/preprocessing.py", line 147, in clip_audio ****!!!****
    os.makedirs(os.path.dirname(save_to))                                         ****!!!****
  File "/home/WNeill/anaconda3/lib/python3.8/os.py", line 223, in makedirs
    mkdir(name, mode)
FileExistsError: [Errno 17] File exists: '/home/WNeill/clipped/clipped/aldfly'

我想不出还有什么其他原因导致第 147 行,对应上面的代码 sn-p(也在堆栈跟踪中标记)执行。

问题:

我该如何解决这个问题(不管我的假设是否正确)?

建议的解决方案:

我唯一的想法可能是使用参数exist_ok=True 并摆脱if 语句。如果我使用这种方法,我害怕覆盖工作。我有大约 8 小时的处理时间,如果某些内容被删除/覆盖,我会很不高兴。

【问题讨论】:

  • Gibbs 规则#18:先不要问,创建目录并在出现异常时处理。
  • @KlausD。最好请求宽恕而不是允许。我上周在 PEP(?) 编码风格指南中读到了这一点。我应该想到这一点(但我会给自己一个通过,因为我还在学习)。谢谢提醒!

标签: python multiprocessing filesystems threadpool


【解决方案1】:

一个有点大的解决办法是参考这个帖子Python sharing a lock between processes

您可以使用那里提到的ManagerLock 在该部分代码中创建一个关键部分。换句话说,这将导致第一个到达那里的线程阻止其他线程执行该部分代码,只有在锁被释放后,它们才能继续他们的快乐方式。

【讨论】:

  • 谢谢 :) 我选择使用 try-except 块,但我喜欢你的回答。我将选择你的作为解决方案,因为它有效并且没有其他人愿意尝试。干杯!
猜你喜欢
  • 2015-03-14
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多