2014-12-26 5 views
-3

Этот простой кодИсключение в «с» блок заготовок файл открыт для записи

# This code will BLANK the file 'myfile'! 
with open('myfile', 'w') as file: 
    raise Exception() 

, а не просто бросать исключение, удаляет все данные в «MYFILE», хотя никакой фактической операции записи не даже попытки.

Это, по меньшей мере, опасно, и, конечно, не то, как другие языки относятся к таким ситуациям.

Как я могу предотвратить это? Должен ли я обрабатывать все возможные исключения, чтобы быть уверенным, что целевой файл не будет заглушен каким-либо непредвиденным условием? Разумеется, для решения этой проблемы должен быть стандартный шаблон. И, прежде всего: что здесь происходит в первую очередь?

+0

Это потому, что режим «w» или «запись» по умолчанию будет сначала обрезать файл. Это делается в то время, когда происходит «open (..)». – SuperSaiyan

+0

Вы ошибаетесь, каждый язык, который я знаю, будет обрезать файл по умолчанию, когда вы откроете его для записи, независимо от того, сколько (если оно есть) вы затем напишите на него. –

+0

Это поведение не имеет ничего общего с Python. Это определенная семантика системного вызова 'open' под POSIX/Unix/Linux, OS X и Windows. Если вы хотите изменить это поведение на Python, вам нужно опуститься до уровня ОС с помощью [os.open] (http://linux.die.net/man/2/open), в частности, опустив константу «O_TRUNC» из *Режим*. – msw

ответ

2

Вы открываете файл для записи. Это , что простое действие, которое закроет файл, независимо от того, что вы делаете с ним. Из open() function documentation:

'w'
открыт для записи, усечение файла первый

Упор шахты. По сути, файл пуст, потому что вы ничего не пишете ему, а не потому, что вы его открыли.

Отложить открытие файла до точки, в которой у вас действительно есть данные для записи, если вы не хотите, чтобы это произошло. Написание списка строк в файл не приведет к исключениям на уровне Python.

В качестве альтернативы напишите в файл и переименуйте его (переместите), чтобы заменить оригинал. Переименование файла, оставленного ОС.

+0

И если у меня есть данные для записи, но при записи возникает ошибка? – user4395564

+0

@ user4395564: тогда вы все еще освободили файл. Если вы гарантировали, что у вас есть готовые данные, то по крайней мере это исключение не будет вызвано вашей программой Python; остается только преждевременное завершение работы (программы или машины) или проблемы с диском (не больше дискового пространства и т. д.). –

0

Заявление open('myfile', 'w')будет удалить все содержимое на выполнение т.е. усечение файла.

Если вы хотите сохранить линии, вы должны использовать open('myfile', 'a'). Здесь опция a предназначена для append.

+0

Но тогда OP не будет * заменять * информацию, если не происходит никакого исключения. –

+0

@MartijnPieters Не так ли непонятно, что OP хочет делать после вызова 'open'. –

+0

Нет, но добавление - это совсем другой вид операции. Лучше писать в новый файл и заменить ОС на старый. –

0

Открытие файла для записи стирает содержимое. Лучший способ избежать потери данных не только в случае исключений, но и выключение компьютера и т. Д. - создать новый временный файл и переименовать файл в исходное имя, когда все будет сделано.

yourfile = "myfile" 
try: 
    with tempfile.NamedTemporaryFile(dir=os.path.dirname(yourfile) or '.', delete=False) as output: 
     do_something() 
except Exception: 
    handle_exception() 
else: 
    os.rename(output.name, yourfile) 
Смежные вопросы