简体   繁体   中英

Why does this except block not catch FileExistsError?

I'm trying to rename a file, but if the file name already exists to just move on. The script stops with FileExistsError exception raised, although I think I'm telling it to look for that? Yes, when the exception is raised the file does already exist.

try:
    # rename the file
    os.rename(infilename, newname)
except FileExistsError:
    # output if it exists already
    print(f'{newname} already exists')
    pass

Traceback is:

Exception has occurred: FileExistsError
[WinError 183] Cannot create a file when that file already exists: 'C:\\Users\\MacalusoC\\Desktop\\PNC_to_Evo\\Evo DECO-10\\Evo PROG6001  FSJD0250240M  E.DBP' -> 'C:\\Users\\MacalusoC\\Desktop\\PNC_to_Evo\\Evo DECO-10\\Evo PROG6001  FSJD0250240M  E.part'
  File "C:\Users\MacalusoC\Desktop\PNC_to_Evo\PNC_Deco_to_Evo_Deco.py", line 75, in purge_DBP_files
    os.rename(infilename, newname)
  File "C:\Users\MacalusoC\Desktop\PNC_to_Evo\PNC_Deco_to_Evo_Deco.py", line 341, in main
    purge_DBP_files(new_folder)
  File "C:\Users\MacalusoC\Desktop\PNC_to_Evo\PNC_Deco_to_Evo_Deco.py", line 350, in <module>
    main()

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None) Rename the file or directory src to dst. If dst is a directory, OSError will be raised. On Unix, if dst exists and is a file, it will be replaced silently if the user has permission. The operation may fail on some Unix flavors if src and dst are on different filesystems. If successful, the renaming will be an atomic operation (this is a POSIX requirement). On Windows, if dst already exists, OSError will be raised even if it is a file. [1] https://docs.python.org/3/library/os.html

So either, the exception is not thrown because you are on a unix system or you are catching the wrong exception.

Why not flip your logic? It's often better to check if something can be done first rather than try it and see if it fails.

from os import path, rename

if not path.exists(newname):
    rename(infilename, newname)

The code below will try to rename a file. See the preconditions check

import os


def rename_file(current_file_name, new_file_name):
    """ rename a file if 'current_file_name' exists and 'new_file_name' doesnt exist 

    :param current_file_name: 
    :param new_file_name: 
    :return: 
    """
    if os.path.exists(new_file_name) or not os.path.exists(current_file_name):
        return
    else:
        os.rename(current_file_name, new_file_name)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM