标签云

微信群

扫码加入我们

WeChat QR Code

How do I see if a file exists or not, without using the try statement?


concerning the first remark (use "try" if check before open) unfortunately this will not work if you want to open for appending being sure it exists before since 'a' mode will create if not exists.

2018年08月16日26分59秒

I get os.path.isfile doesn't exist.

2018年08月16日26分59秒

having multiple conditions, some of which are superfluous, is less clear and explicit.

2018年08月15日26分59秒

It is also redundant. If the file doesn't exist, os.access() will return false.

2018年08月15日26分59秒

EJP In linux files can exist but not accesible.

2018年08月15日26分59秒

This answer is wrong. os.path.exists returns true for things that aren't files, such as directories. This gives false positives. See the other answers that recommend os.path.isfile.

2018年08月16日26分59秒

As long as you intend to access the file, the race condition does exist, regardless of how your program is constructed. Your program cannot guarantee that another process on the computer has not modified the file. It's what Eric Lippert refers to as an exogenous exception. You cannot avoid it by checking for the file's existence beforehand.

2018年08月15日26分59秒

IsaacSupeene Best practice is to make the window of (file) operation as small as possible followed by a proper exception handling

2018年08月16日26分59秒

Can you elaborate on this statement? "Although it's not a good practice, I'm using os.F_OK in the call, but that's just for clarity (its value is 0)"

2018年08月15日26分59秒

sk8asd123: Kind of hard to doo it in a comment: generally, it's best to use constants with functions that they come together with. That applies when working with multiple modules that define the same constant, because some might not be up to date, and it's best for the functions and constants to be in sync. When working with ctypes (calling the functions directly) I should have defined the constant (from MSDN), or not use a constant at all. It's just a guideline that I use, in 99.9% it probably makes no difference (functionally).

2018年08月16日26分59秒

CristiFati: As of 3.6, glob.iglob (and glob.glob as well) are based on os.scandir, so it's lazy now; to get the first hit in a directory of 10M files, you only scan until you reach the first hit. And even pre-3.6, if you use glob methods w/o any wildcards, the function is smart: It knows you can only have one hit, so it simplifies the globbing to just os.path.isdir or os.path.lexists (depending on whether path ends in /).

2018年08月16日26分59秒

That second part of my comment (non-wildcarded globbing doesn't actually iterate the folder, and never has) does mean it's a perfectly efficient solution to the problem (slower than directly calling os.path.isdir or os.path.lexist since it's a bunch of Python level function calls and string operations before it decides the efficient path is viable, but no additional system call or I/O work, which is orders of magnitude slower).

2018年08月16日26分59秒

Please add better sources to support your statement.

2018年08月16日26分59秒

The cited Avoiding Race Conditions (apple dev support) link does not support your answer. It concerns only using temporary files that contain sensitive information on poorly designed operating systems that don't properly sandbox temporary files / directories via restricted permissions. Using try...except doesn't help resolve that problem anyway.

2018年08月15日26分59秒

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review

2018年08月15日26分59秒

chrisz I don't think that it's link-only - it actually has information other than the link.

2018年08月15日26分59秒

This answer is wrong. os.path.exists returns true for things that aren't files, such as directories. This gives false positives. See the other answers that recommend os.path.isfile.

2018年08月16日26分59秒

This answer is wrong. os.path.exists returns true for things that aren't files, such as directories. This gives false positives. See the other answers that recommend os.path.isfile.

2018年08月16日26分59秒

On your third example, I create a link named filepath with the right timing, and BAM, you overwrite the target file. You should do open(filepath, 'wx') in a try...except block to avoid the issue.

2018年08月16日26分59秒

In your second example, at least in Windows, you will get an OSError if filepath + '.old' already exists: "On Windows, if dst already exists, OSError will be raised even if it is a file; there may be no way to implement an atomic rename when dst names an existing file."

2018年08月16日26分59秒

TomMyddeltyn: As of Python 3.3, os.replace portably performs silent replacement of the destination file (it's identical to os.rename's Linux behavior) (it only errors if the destination name exists and is a directory). So you're stuck on 2.x, but Py3 users have had a good option for several years now.

2018年08月15日26分59秒

On the rename example: It should still be done with try/except. os.rename (or os.replace on modern Python) is atomic; making it check then rename introduces an unnecessary race and additional system calls. Just do try: os.replace(filepath, filepath + '.old') except OSError: pass

2018年08月16日26分59秒

May I ask: What's the advantage of using the module 'pathlib' instead of the module 'os' in python3 for this checking?

2018年08月15日26分59秒

pathlib is python's OOP solution for paths. You can do a lot more with it. If you just need to check existance, the advantage is not so big.

2018年08月15日26分59秒

The original question asked for a solution that does not use try

2018年08月15日26分59秒

This answer misses the point of the OP. Checking is a file exists is not the same as checking if you can open it. There will be cases where a file does exist but for a variety of reasons, you can't open it.

2018年08月16日26分59秒

How is this any different from Cody Piersall's answer?

2018年08月15日26分59秒

The OP asked how to check if a file exists. It's possible for a file to exist but for you to not be able to open it. Therefore using opening a file as a proxy for checking if the file exists is not correct: will have false negatives.

2018年08月15日26分59秒

One-line check in bash: [ -f "${file}" ] && echo "file found" || echo "file not found" (which is the same as if [ ... ]; then ...; else ...; fi).

2018年08月15日26分59秒

if (x) return true; else return false; is really just return x. Your last four lines can become return os.path.isfile(file_path). While we're at it, the whole function can be simplified as return file_path and os.path.isfile(file_path).

2018年08月15日26分59秒

You have to be careful with return x in the case of if (x). Python will consider an empty string False in which case we would be returning an empty string instead of a bool. The purpose of this function is to always return bool.

2018年08月15日26分59秒

True. In this case however, x is os.path.isfile(..) so it's already bool.

2018年08月16日26分59秒

os.path.isfile(None) raises an exception which is why I added the if check. I could probably just wrap it in a try/except instead but I felt it was more explicit this way.

2018年08月16日26分59秒

return file_path and os.path.isfile(file_path)

2018年08月16日26分59秒

you have an error, it is os.path.exists not os.path.exist you are missing an s

2018年08月15日26分59秒

This answer is wrong. os.path.exists returns true for things that aren't files, such as directories. This gives false positives. See the other answers that recommend os.path.isfile.

2018年08月16日26分59秒

Chris Johnson , os.path.exists() function checks whether a path exists in system. PATH may be a DIRECTORY or FILE. It will work fine on both the cases. Please try with some example

2018年08月15日26分59秒

So, this answer works. Great. Iff the path isn't that of a file. Is that what the question was about? No.

2018年08月15日26分59秒

It depends. If the goal of determining the existence of a "file" is to find out whether the path already exists (and is therefore not a path where new data can be stored without deleting other information), then exists is fine. If the goal is to determine whether it's safe to open a presumably existing file, then the criticism is justified and exists is not precise enough. Sadly, the OP doesn't specify which is the desired goal (and probably won't do so any more).

2018年08月16日26分59秒

This answer is wrong. os.path.exists returns true for things that aren't files, such as directories. This gives false positives. See the other answers that recommend os.path.isfile.

2018年08月16日26分59秒

got the false positive problem also.

2018年08月15日26分59秒

This is wrong on two counts: (1) os.walk find all files under a directory tree -- if the user wants to check for ./FILE, it's unlikely he'd want to treat ./some/sub/folder/FILE as a match, which your solution does; and (2) your solution is very inefficient compared to a simple os.path.isfile() call in the case where there are many files below the current directory. In the case where no matching filename-without-path exists within the tree, your code will enumerate every single file in the tree before returning false.

2018年08月16日26分59秒