当文件不存在时,os.access返回False,而不管传递的模式参数是什么。
这在the documentation for ^{}中没有明确说明,但这并不是非常令人震惊的行为;毕竟,如果一个文件不存在,就不可能访问它。按照文档的建议检查the access(2) man page提供了另一个线索,即access在各种条件下返回-1。在任何情况下,您都可以像我所做的那样,在IDLE中检查返回值:>>> import os
>>> os.access('does_not_exist.txt', os.R_OK)
False
在Python中,通常不鼓励在尝试实际做有用的事情之前检查类型等。这一理念通常用缩写EAFP来表达,EAFP代表着请求宽恕比请求许可更容易。如果您再次查阅这些文档,您会发现这在本例中特别重要:Note: Using access() to check if a user is authorized to e.g. open a file before actually doing so using open() creates a security
hole, because the user might exploit the short time interval between
checking and opening the file to manipulate it. It’s preferable to use
EAFP techniques. For example:if os.access("myfile", os.R_OK):
with open("myfile") as fp:
return fp.read()
return "some default data"
is better written as:try:
fp = open("myfile")
except IOError as e:
if e.errno == errno.EACCES:
return "some default data"
# Not a permission error.
raise
else:
with fp:
return fp.read()
如果除了在调用open()之前对用户进行二次猜测之外,还有其他原因需要检查权限,可以向How do I check whether a file exists using Python?寻求一些建议。记住,如果你真的需要提出一个例外,你可以自己解决;不需要在野外寻找。Since the IOError can be brought up a couple different ways (such as
permission denied, or non-existent directory), I am trying to get my
module to identify and publish the issue.
以上第二种方法就是这样。见:>>> try:
... open('file_no_existy.gif')
... except IOError as e:
... pass
...
>>> e.args
(2, 'No such file or directory')
>>> try:
... open('unreadable.txt')
... except IOError as e:
... pass
...
>>> e.args
(13, 'Permission denied')
>>> e.args == (e.errno, e.strerror)
True
但你需要选择一种方法或另一种方法。如果你请求原谅,试着做一件事,除了阻止和适当地处理后果。如果你成功了,你就知道你成功了,因为没有例外。
另一方面,如果你请求许可(也叫LBYL,在你跳跃之前看一下),那么你仍然不知道是否可以成功打开文件,直到你真正打开它。如果文件在检查其权限后被移动怎么办?如果有什么问题你不想查呢?
如果你还想请求许可,不要使用try-except;你没有做这件事,所以你不会抛出错误。相反,使用带有对os.access的调用的条件语句作为条件。