【问题标题】:os.mkdir(path) returns OSError when directory does not existos.mkdir(path) 在目录不存在时返回 OSError
【发布时间】:2013-09-29 04:27:20
【问题描述】:

我正在调用os.mkdir 来创建一个包含特定生成数据集的文件夹。但是,即使我指定的路径尚未创建,os.mkdir(path) 也会引发 OSError 表明路径已存在。

例如,我调用:

os.mkdir(test)

即使我在任何地方都没有测试目录或名为 test 的文件,此调用也会导致 OSError: [Errno 17] File exists: 'test'

注意:我使用的实际路径名不是“test”,而是更模糊的东西,我确定没有在任何地方命名。

请帮忙?

【问题讨论】:

    标签: python system mkdir


    【解决方案1】:

    格雷格的回答是正确的,但还远远不够。 OSError 有子错误条件,你不想每次都压制它们。仅捕获预期操作系统错误是谨慎的做法。

    在决定禁止异常之前进行额外检查,如下所示:

    import errno
    import os
    
    try:
        os.mkdir(dirname)
    except OSError as exc:
        if exc.errno != errno.EEXIST:
            raise
        pass
    

    您可能不想抑制 errno.EACCES(权限被拒绝)、errno.ENOSPC(设备上没有剩余空间)、errno.EROFS (只读文件系统)等。或者您可能确实想要 - 但这需要根据您正在构建的特定逻辑做出有意识的决定。

    Greg 的代码抑制了所有操作系统错误;这不安全,就像 except Exception 不安全一样。

    正如其他人所指出的,较新版本的 Python 提供了 os.makedirs(),它仅在目录不存在时才尝试创建它,相当于 unix 命令行中的 mkdir -p

    【讨论】:

    • 这是唯一正确的答案。其他人建议的使用 os.path.exists 的“先看一下”方法会产生竞争条件:完全有可能在 exists 和 mkdir/makedirs 调用之间创建文件/目录,这将产生未处理的异常。
    • 不是“唯一正确的答案”,因为竞争条件在所有(甚至可能是大多数)用例中都不是相关问题。
    • @oseiskar,当正确的方法比错误的方法更容易或更容易时,每次都不以正确的方法做是不负责任的。如果你每次都以正确的方式去做,你就不必浪费时间和精力去思考它。优秀的开发人员专注于养成良好的习惯。
    • @ChrisJohnson 是的,但在这种情况下,“as easy”在可读性方面是有问题的。这些不同方面之间的正确平衡取决于您的用例。牺牲可读性以抵抗环境中从未发生过的竞争条件是过早的优化。
    • @oseiskar,我展示的是 Python 开发人员的常规方法。如果它不可读,那么阅读它的人就不会很好地理解 Python。除非您在单线程操作系统上运行,否则这种特定竞争条件的可能性始终存在。
    【解决方案2】:

    在 Python 3.2 及以上版本中,您可以使用:

    os.makedirs(path, exist_ok=True)

    避免在目录已经存在时出现异常。如果path 存在并且不是目录,这仍然会引发异常。

    【讨论】:

    • makedirs 中使用exist_ok=True 仍然会引发FileExistsError,如果目标路径存在并且它不是目录(文件、块设备等):(
    • @nadrimajstor 这是一个很好的观点,这不是捕获 FileExistsError 的直接替代品,尽管当您尝试在文件。
    【解决方案3】:

    只需检查路径是否存在。如果不创建它

    import os    
    if not os.path.exists(test):
        os.makedirs(test)
    

    【讨论】:

    • 此答案不正确且危险。它创建了一个竞争条件,因为该目录可以在exists 调用之后和makedirs 调用之前由另一个进程创建。请参阅我的答案以获得适当的解决方案。
    • 呵呵你认为这两个语句之间会有多少毫秒:) 但是你是对的:)
    • 它会经常发生,足以让你疯狂地尝试调试它:)
    • 你在什么样的环境中工作?有多少个进程?
    • 某位名人曾经说过:百万分之一的机会是下周二。
    【解决方案4】:

    在 Windows 上发生在我身上,也许是这种情况:

    像你一样,我试图:

    os.mkdir(dirname)
    

    得到OSError: [Errno 17] File exists: '<dirname>'。 我跑的时候:

    os.path.exists(dirname)
    

    我弄错了,这让我发疯了一阵子:)

    问题是:在某个窗口中,我位于特定目录。即使它当时不存在(我从 linux 中删除了它)。解决方案是关闭该窗口\导航到其他地方。 可耻,我知道...

    【讨论】:

    • 感谢您在 3 小时的绝望调试后恢复了理智!从一个终端我有'cd mydir',然后ssh'ed到另一台机器,我无法看到我仍在'mydir'中......
    【解决方案5】:

    我也遇到了同样的问题,特别是当字符串“test”包含多个目录名称时。 所以当 'test' 包含单个目录时 -

    if not os.path.exists(test):
        try:
            os.makedir(test)
        except:
            raise OSError("Can't create destination directory (%s)!" % (test))  
    

    如果 'test' 包含多个目录,例如 '\dir1\dir2' 然后 -

    if not os.path.exists(test):
        try:
            os.makedirs(test)
        except:
            raise OSError("Can't create destination directory (%s)!" % (test))  
    

    【讨论】:

    • if 毫无用处。
    • if 语句可防止覆盖现有同名目录。
    • 不,它没有。无论您之前是否检查,操作系统都会阻止覆盖。除非您在单线程操作系统上运行,否则在您检查目录不存在并尝试创建目录之后,另一个进程可以创建目录。捕获异常的重点是处理如果目录已经存在会发生什么,无论它是上周还是 1 微秒前存在。 if 毫无用处。 try/except 是唯一可靠的方法。
    【解决方案6】:

    您有一个名为test 的文件。您不能创建具有完全相同名称的目录。

    【讨论】:

      【解决方案7】:

      简单的答案,不需要任何额外的导入,不会抑制诸如“权限被拒绝”、“设备上没有剩余空间”等错误,但接受目录可能已经存在:

      import os
      
      try:
          os.mkdir(dirname)
      except FileExistsError :
          pass
      except :
          raise
      

      【讨论】:

        【解决方案8】:

        我不知道您的文件系统的细节。但是如果你真的想解决这个问题,也许可以使用 try/except 子句?

        try:
            os.mkdir(test)
        except OSError:
            print "test already exists"
        

        您总是可以同时进行某种调试。

        【讨论】:

        • 报错信息不正确。 OSError 异常可能由于多种原因而发生,例如权限不足或只读文件系统。您不能断定该目录已经存在。需要检查exc.errno的值来判断异常原因。
        【解决方案9】:

        也许该目录中有一个名为 test 的隐藏文件夹。手动检查是否存在。

        ls -a

        仅当文件不存在时才创建。

        if not os.path.exists(test):
            os.makedirs(test)
        

        【讨论】:

        • 此答案不正确且危险。它创建了一个竞争条件,因为该目录可以在exists 调用之后和makedirs 调用之前由另一个进程创建。请参阅我的答案以获得适当的解决方案。
        • 如果被隐藏了,就不可能叫test吧?它必须是.test,这是一个不同的字符串
        【解决方案10】:

        对于 python 2.7

        from distutils.dir_util import mkpath
        mkpath(path)
        

        【讨论】:

          【解决方案11】:

          没有看到有关此特定解决方案的任何其他答案或 cmets。但请确保您是否正在积极管理您退出并在运行代码之前重新登录的文件夹权限。我把头撞在墙上大约一个小时,试图弄清楚我的问题是什么,就是这样。

          【讨论】:

            猜你喜欢
            • 2016-02-05
            • 1970-01-01
            • 2017-06-17
            • 1970-01-01
            • 1970-01-01
            • 2023-02-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多