使用Python检查是否可以将文件写入目录

17

我需要检查是否可以使用Python将文件写入用户指定的目录。

有没有一种方法可以提前检查呢?我可能会使用try...catch来达到这个目的,但我希望有更好的方法可以事先检查。


3
为什么你期望有更好的东西呢?在 Python 中,异常处理是一种廉价且标准的错误处理方式。 - Jim Brissom
@Jim:感谢您的评论,我稍微详细阐述了一下这篇文章。 - prosseek
1
在Python中,异常并不便宜,但请参阅我的答案以获取更多详细信息 - 特别是,os.access和stat仍然无法为您提供真正的安全性,并实际上为竞争条件创造了机会。尽管如此,它们仍然可以改善用户体验。 - user79758
@S.Lott:我修改了那个含有“危险”一词的句子。 - prosseek
“异常很昂贵”是错误的。 异常非常快。为什么要避免它们? 为什么要从操作系统中取走责任? 为什么要复制已经存在于操作系统中的逻辑来验证您的请求? “愤怒”是你的问题,不是我的问题。 我只是在问问题 - 为什么要把那标记为“愤怒”? 为什么要复制拒绝不当请求的操作系统功能? - S.Lott
显示剩余2条评论
4个回答

22

尽管Jim Brissom声称,在Python中,与“检查再尝试”惯用语相比,异常处理并不是便宜的,如果你预计这个东西会超过几个百分点失败。 (请阅读到最后一个例外!)然而,关键在于您仍然需要检查异常,因为权限可能会在检查和写入之间更改:

### !!! This is an example of what not to do!
### !!! Don't do this!
if os.access("test", os.W_OK):
    # And in here, some jerk does chmod 000 test
    open("test", "w").write(my_data)
    # Exception happens despite os.access!

如果你想准备一个文件夹列表供用户选择,并想要预先排除无效的文件夹,那么os.access和stat模块非常有用。但是,在实际运行时,如果你想让程序更加健壮,它并不能替代异常处理。

现在来说一下异常处理的例外:异常处理虽然会使程序变慢,但是与磁盘相比,磁盘的速度更慢。如果你的磁盘负载特别重,可能会出现你所感兴趣的文件在os.access和打开调用之间被操作系统或磁盘高速缓存中删除的情况。这种情况下,你将会遇到很大的减速,因为你需要两次访问磁盘(现在可能还包括网络)。


4

3
重申Python的哲学并不讨论为什么异常处理是更好的解决方案,此处评分为-1。 - user79758
@Joe:我链接了Python的哲学。此外,它之所以成为一种哲学,是因为它在Python中以及其他地方都很有效。例如,它对于鸭子类型非常有用。 - Muhammad Alkarouri
Python词汇表并没有解释它为什么有用; 实际上,它将其描述为“简洁和快速”,而我对这两者都强烈不同意。 - user79758
1
@Joe:我同意它不够快,但在我看来它很干净。更重要的是,EAFP从与你不同的角度解决问题。你的答案是“因为竞态条件”,这是正确的,但与编程语言无关。我的答案是“使用EAFP”,因为它在Python中对各种事情都很有用,而不仅仅是因为竞态条件。OP可能会发现两个答案在不同方面都很有用。 - Muhammad Alkarouri

2

Pythonic的方式是去访问它,如果失败则捕获异常。

如果你真的需要检查它,可以使用os.access,但结果并不总是正确的,请注意在Vista/Win7中可能会出现UAC问题!

示例:

os.access(r'C:\Programme', os.R_OK)

这将告诉您是否具有读取权限。

1

只需使用这个:

def check_access(file, mode):
   try:
      open(file, mode)
      return True
   except PermissionError:
      return False
print(check_access("test", "w"))

如果没有权限,将输出以下内容:

False

如果有权限,则输出:

True

如果您使用os.access(),那么您有可能会得到类似以下的内容:

   Traceback (most recent call last):
 File "/Users/lawrence/Library/Application Support/CodeRunner/Unsaved/Untitled.py", line 8, in <module>
   open("test", "w").write("test")
 PermissionError: [Errno 13] Permission denied: 'test'

你仍然可以使用os.access(),但我不建议这样做


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接