Делаем безопасную перезапись файла с помощью менеджера контекста

  Рет қаралды 2,760

Хитрый питон

Хитрый питон

3 жыл бұрын

Контекстные менеджеры - очень полезная штука в python. Давайте разберем использование context manager на примере atomic write. Т.е. если в процессе записи информации в файл произойдет ошибка, мы должны откатиться к предыдущей версии файла.
Я в Telegram - t.me/tricky_python
Канал создан при поддержке сообщества Moscow Python.
Наш KZfaq-канал - / @moscowdjangoru
Курсы Learn Python - learn.python.ru/

Пікірлер: 17
@evgeninobility368
@evgeninobility368 2 жыл бұрын
Огромное спасибо за тему! Очень подсобила) P.S: Если файл уже существует, то os.rename выдаст: [WinError 183] то есть 'Невозможно создать файл, так как он уже существует.' В этом случае нужно использовать os.replace
@evgeninobility368
@evgeninobility368 2 жыл бұрын
ну, либо же перед os.rename(".....", self.path) поставить os.remove(self.path) как я и сделал)
@markgold1600
@markgold1600 3 жыл бұрын
Спасибо за выпуск!
@86Blind
@86Blind 2 жыл бұрын
Супер объяснение. Спасибо большое !!!!
@dmitryzagorevskiy507
@dmitryzagorevskiy507 3 жыл бұрын
Михаил, благодарю! Взял в pet project
@sainco3036
@sainco3036 3 жыл бұрын
спасибо, пригодится.
@BochkovAlexey
@BochkovAlexey 9 ай бұрын
Михаил благодарю! У Вас очень полезные видео!!! Код из данного видео на Linux Fedora завершается с ошибкой oserror errno 18 invalid cross-device link, видимо действительно блок try exept обязателен в данном примере, методом тыка в exept отработал shutil.move, если есть возможность скажите, правильное ли это решение данной проблемы? Если нет, то как было бы правильно, все таки хочется писать рабочий код из примеров!
@e_butcher
@e_butcher 3 жыл бұрын
Спасибо. А для чего используются менеджеры with close? Встречал в некоторых скриптах
@RomanTimofeev
@RomanTimofeev 3 жыл бұрын
Целая пачка ошибок. 1. Файл читается целиком в память(да, понимаю что пример, но не надо так) 2. rename/unlink вполне себе могут закончится ошибкой(например, path="/root/test.txt", а вы под обычным пользователем). 3. close(2) тоже вполне себе может выбрасывать ошибки
@user-th6xg5bk4c
@user-th6xg5bk4c 3 жыл бұрын
1. Файл тут читается только чтобы показать его содержимое и к задаче не особо относится. Можно сделать !cat или написать больше строчек - но зачем? 2 и 3. В этом случае исходный файл не перезапишется. Предположим unlink здесь не сработает только в каких-то прямо очень специфических случаях, а rename можно дополнительно обложить try/except-ом но это кажется переусложнит пример
@RomanTimofeev
@RomanTimofeev 3 жыл бұрын
@@user-th6xg5bk4c > unlink здесь не сработает только в каких-то прямо очень специфических случаях На windows достаточно файл открыть на чтение, на linux есть fanotify(7) > rename можно дополнительно обложить try/except Не просто можно, а нужно. Потому что в текущем примере на linux будет вызываться ветка с os.unlink. Происходить это будет потому что os.rename будет выбрасывать OSError из-за попыток перемещения между разными mount points("Invalid cross-device link" и вот это всё). Происходить это будет потому что /tmp живёт в tmpfs, а os.rename перемещает за её пределы. И даже если заменить на shutil.move всё равно проблемы останутся и ошибки надо обрабатывать. И, строго говоря, реализация не является безопасной из-за имеющихся data races. Например, у нас 2 экземпляра программы захотели модифицировать 1 файл.
@FaiverBES
@FaiverBES 3 жыл бұрын
Взял себе на заметку, спасибо. Немного не понял, про exc_type и exc_message. Мы же вроде их явно не передаём, получается Python их передаёт как параметры по умолчанию? И что ещё он туда может передавать?
@user-th6xg5bk4c
@user-th6xg5bk4c 3 жыл бұрын
Это сигнатура метода __exit__() - т.е. python сам туда эти вещи передает при его вызове (выходе из блока или возникновению исключения внутри блока)
@user-ie3zj8rw5r
@user-ie3zj8rw5r 2 ай бұрын
1)problem OSError: [WinError 17] Системе не удается переместить файл на другой диск: 'C:\\Users\\Sergei\\AppData\\Local\\Temp\\tmp2m46kr87' -> 'text.txt' 2)decision def __exit__(self, exc_type, exc_val, exc_tb): self.temp_file.close() shutil.move(...)
ВОДА В СОЛО
00:20
⚡️КАН АНДРЕЙ⚡️
Рет қаралды 28 МЛН
아이스크림으로 체감되는 요즘 물가
00:16
진영민yeongmin
Рет қаралды 62 МЛН
КАК ДУМАЕТЕ КТО ВЫЙГРАЕТ😂
00:29
МЯТНАЯ ФАНТА
Рет қаралды 9 МЛН
Изучение Java с нуля / #23 Static
17:01
Evgeny Orashkov
Рет қаралды 68
Улучшаем код с помощью генераторов
6:56
Хитрый питон
Рет қаралды 4 М.
Что такое атрибуты класса в python?
8:42
Хитрый питон
Рет қаралды 4,5 М.
Как использовать *args и **kwargs в python?
11:22
Хитрый питон
Рет қаралды 6 М.
GitHub Actions для автоматической проверки кода
14:03
Хитрый питон
Рет қаралды 11 М.
ВОДА В СОЛО
00:20
⚡️КАН АНДРЕЙ⚡️
Рет қаралды 28 МЛН