Os.rename не вызывает FileExistsError, когда файл существует

У меня есть механизм file_rename, который я хочу улучшить с помощью простого блока try/except, который будет проверять, существует ли уже переименованный файл в каталоге.

Я подготовил в своем каталоге 2 файла: data.txt и old_data.txt. Функция должна генерировать исключение, так как old_data.txt уже существует, что означает, что данные были обработаны в прошлом.

Однако приведенный ниже код не работает, так как он все еще переименовывает файл data.txt. Буду признателен за любую помощь и рекомендации по этому поводу.

@staticmethod
def file_rename(file, dir):
    source_file_new_name = "old_" + file
    try:
        os.path.isfile(dir + source_file_new_name)
        os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name))
    except FileExistsError:
        raise FileExistsError("this file was already processed")

С подсказкой Rafał и BrokenBenchmark я придумал версию ниже, но не уверен, что она достаточно питоническая;)

class FileExistsError(Exception):
    pass

@staticmethod
def file_rename(file, dir):
    source_file_new_name = "old_" + file

    if os.path.isfile(dir + source_file_new_name):
        raise FileExistsError("this file was already processed!")
    else:
        os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name))

Какую ОС вы используете?

BrokenBenchmark 19.03.2022 23:33

Ubuntu на WSL2/Windows 10

marcin2x4 19.03.2022 23:35

Превосходно; отредактируйте это в своем посте. Это важно, напишите ответ сейчас.

BrokenBenchmark 19.03.2022 23:38
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
3
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Метод os.path.isfile просто возвращает True (если файл существует) или False (если его нет). Используйте оператор if, чтобы проверить его результат перед вызовом os.rename.

Не уверен, насколько питоническим это будет, но raise можно использовать и в блоке if: if os.path.isfile(dir + source_file_new_name): os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name)) raise FileExistsError("this file was already processed")

marcin2x4 19.03.2022 23:54

Вы можете, но должны ли вы? Честно говоря, это в основном зависит от ваших личных предпочтений в отношении того, как обрабатывать логические ошибки. Например. поиск EAFP (проще попросить прощения, чем разрешения) как общий стиль кодирования Python.

Rafal Gradkowski 20.03.2022 00:53

Ваш код предполагает, что os.rename вызовет FileExistsError. Это предположение можно сделать только в том случае, если код выполняется в Windows.Документы Python для состояния os.rename():

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)

Rename the file or directory src to dst. If dst exists, the operation will fail with an OSError subclass in a number of cases:

On Windows, if dst exists a FileExistsError is always raised.

On Unix, ... [i]f both [src and dst] are files, dst it [sic] will be replaced silently if the user has permission.

Чтобы решить эту проблему, используйте оператор if с .isfile() вместо того, чтобы полагаться на try/except, который зависит от поведения, которое не является переносимым для работы:

def file_rename(file, dir):
    source_file_new_name = "old_" + file
    if os.path.isfile(os.path.isfile(dir + source_file_new_name)):
        os.rename(os.path.join(dir, file), os.path.join(dir, source_file_new_name))

Не уверен, насколько питоническим это будет, но повышение можно использовать и внутри блока if: if os.path.isfile(dir + source_file_new_name): os.rename(os.path.join(dir, file), os.path.join( dir, исходный_файл_новое_имя)) поднять FileExistsError("этот файл уже был обработан")

marcin2x4 19.03.2022 23:54

Лично я бы не стал поднимать ошибку только для того, чтобы сразу ее отловить; это добавляет ненужную сложность вашему коду, так как if/else было бы проще. Но это более субъективно, чем первоначальная проблема.

BrokenBenchmark 20.03.2022 00:07

В моем случае я буду придерживаться его, так как мне нужно прервать выполнение кода, чтобы не загружать данные в базу данных. Тот фрагмент, который я разместил, является частью сценария ELT.

marcin2x4 20.03.2022 01:02

Другие вопросы по теме