os.mkdir(path) returns OSError when directory does not exist
我打电话给os.mkdir创建一个文件夹,其中包含一组生成的数据。但是,即使我指定的路径尚未创建,os.mkdir(path)也会引发一个已存在该路径的osError。
例如,我调用:
这个调用会导致OSError: [Errno 17] File exists: 'test',即使我在任何地方都没有测试目录或名为test的文件。
注意:我使用的实际路径名不是"test",而是一些更模糊的东西,我确信它不会在任何地方命名。
救命,求你了?
格雷格的回答是正确的,但不够深入。OSError有子错误条件,您不希望每次都抑制它们。谨慎的做法是捕获预期的操作系统错误。
在决定抑制异常之前,请执行其他检查,如下所示:
1 2 3 4 5 6 7 8 9
| 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是不安全的。
- 这是唯一正确的答案。使用os.path.exists的"look before you leap"方法是其他人建议的,它创建了一个争用条件:完全有可能在exists和mkdir/makedirs调用之间创建文件/dir,这将生成一个未经处理的异常。
- 这不是"唯一正确的答案",因为在所有(甚至大多数)用例中,竞争条件都不是一个相关的问题。
- @奥西沙尔,当正确的方法比错误的方法容易或容易的时候,每次都不以正确的方式去做是不负责任的。如果你每次都以正确的方式做,你就不必浪费时间和精力去思考它。优秀的开发人员注重培养良好的习惯。
- @克里斯约翰逊是真的,但在这种情况下,"简单"在可读性方面是值得怀疑的。这些不同方面之间的正确平衡取决于您的用例。牺牲可读性来抵抗环境中从未发生的竞争条件是过早的优化。
- @Oseiskar,我展示的是Python开发人员的常规方法。如果它不可读,那么读它的人就不太了解Python。除非您在单线程操作系统上运行,否则这种特殊竞争条件的潜力总是存在的。
- 有两种批评:1)pass是多余的;2)我宁愿raise是赤裸裸的(保留回溯——可能在这里并不重要,但由于善意的编码人员提出了新的错误,丢失了回溯,因此我在丢失回溯方面遇到了问题,因此我知道该如何解决。前)
- 亚伦,我同意。pass只是一种无害的习惯,但raise具有真正的效果。我会修改的。
- 似乎这是一种"请求原谅而不是许可"stackoverflow.com/questions/12265451/…
- @差不多是的。
只需检查路径是否存在。如果不创建它
1 2
| if not os.path.exists(test):
os.makedirs(test) |
号
- 这个答案是错误的和危险的。它创建一个争用条件,因为目录可以在exists调用之后和makedirs调用之前由另一个进程创建。请参阅我的答案以获得正确的解决方案。
- 呵呵,你觉得这两个说法之间会有多少毫秒:)但是的,你是对的:)
- 它会经常发生,足以让你疯狂地尝试调试它:)
- 你工作的环境怎么样?有多少个过程?
- 有位名人曾经说过:下周二是百万分之一的机会。
- 似乎调度器喜欢在操作系统调用之间进行分割,因为这种情况比您想象的更可能发生。我今天刚遇到它,两个线程调用同一个库,基本上在一个带有硬编码目录名的@property&;中包含此代码。
在python 3.2及更高版本中,可以使用:
埃多克斯1〔8〕
以避免在目录已存在时出现异常。如果path存在而不是目录,这仍然会引发异常。
- 在makedirs中使用exist_ok=True仍然会在目标路径存在且不是目录(文件、块设备等)的情况下引发FileExistsError:(
- @nadrimajstor这是一个很好的观点,这并不能代替抓取FileExistsError,尽管当你试图在文件上创建一个目录时,通常你确实需要一个例外。
我还面临同样的问题,特别是当字符串"test"包含多个目录名时。所以当"test"包含单个目录时-
1 2 3 4 5
| if not os.path.exists(test):
try:
os.makedir(test)
except:
raise OSError("Can't create destination directory (%s)!" % (test)) |
。
如果"test"包含多个目录,如'dir1dir2',则-
1 2 3 4 5
| 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是唯一可靠的方法。
在Windows上发生在我身上,也许就是这样:
像你一样,我试图:
。
找到了OSError: [Errno 17] File exists: ''。当我跑步时:
我弄错了,这让我有一段时间发疯了:)
问题是:在某个窗口中,我在特定的目录下。即使它当时不存在(我从Linux中删除了它)。解决方案是关闭该窗口导航到其他地方。可耻,我知道…
您在那里有一个名为test的文件。不能用相同的名称创建目录。
我不知道你的文件系统的细节。但如果你真的想避开这个问题,可以使用try/except子句?
1 2 3 4
| try:
os.mkdir(test)
except OSError:
print"test already exists" |
您可以同时进行某种调试。
- 错误消息不正确。OSError异常可能由于许多原因发生,例如权限不足或只读文件系统。您不能断定目录已经存在。您需要检查EDOCX1[1]的值以确定异常的原因。
可能那个目录中有一个名为test的隐藏文件夹。手动检查是否存在。
江户十一〔一〕号
仅当文件不存在时才创建该文件。
1 2
| if not os.path.exists(test):
os.makedirs(test) |
- 这个答案是错误的和危险的。它创建一个争用条件,因为目录可以在exists调用之后和makedirs调用之前由另一个进程创建。请参阅我的答案以获得正确的解决方案。
- 如果它是隐藏的,就不可能被称为test,对吧?它必须是.test,这是一个不同的字符串