LINUX.ORG.RU

Python - писать в файл, но создать или перезаписать его только в него что-то записывают

 


0

2

Есть ли аналог питоновского open, чтобы открыть файл в режиме 'w' или 'wb', но чтобы если я в этот файл ничего не написал, то чтобы он не создавался, а просто как будто ничего и не открывалось?

Виталик, перелогинься.

По теме. Почему нельзя юзать 'a'/'ab' тогда когда тебе надо записать файл? Если запись происходит из разных участков программы, то можно взять за основу паттерн observer.

fang90 ★★★★★
()
Ответ на: комментарий от fang90

Мне не надо писать из разных частей программы. Мне надо несколько файлов передать программе как аргументы через argparse, после этого выполнить какую-то проверку, связанную с другими аргументами, и если все ок, то открыть эти файлы для записи и дальше с ними работать, а если все не ок, то ничего не открывать. Сейчас юзаю в argparse type=argparse.FileType('w'), и файлы создаются как только все распарсится, и они создаются даже если проверка не пройдена, и программа выходит с кодом ошибки.

hlebushek ★★
() автор топика

Что значит ничего не было? Остаются файлы нулевого размера? Ну, удали их при выходе из программы, в чём проблема то?

justAmoment ★★★★★
()
Ответ на: комментарий от justAmoment

Некрасиво. Намного лучше их вообще не создавать. Ладно если файлов изначально не было - их тогда можно удалить просто. А если файлы были? Условие не пройдено, но эти файлы уже открылись на запись, а значит хоть программа и не дошла до логического конца, она их все равно перезапишет пустышками.

hlebushek ★★
() автор топика

Хочу сделать функцию, суть такова: 3 аргумента, каждый может быть либо файлом, либо строкой (или еще чем-то, что можно подсунуть в open. И соответственно если это файл, то отлично, он уже открыт. А если это не файл, а строка, то засунем ее в open. В нормальном языке программирования я бы использовал какой-нибудь там boost::variant или Either. А как по питонячьи такое сделать?

hlebushek ★★
() автор топика
Ответ на: комментарий от anonymous

Мне нравится, хочу у них это взять. Читаю LICENSE в корне проекта:

Copyright (c) 2014 by Armin Ronacher.

Click uses parts of optparse written by Gregory P. Ward and maintained by the
Python software foundation.  This is limited to code in the parser.py
module:

Copyright (c) 2001-2006 Gregory P. Ward.  All rights reserved.
Copyright (c) 2002-2006 Python Software Foundation.  All rights reserved.

Some rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * The names of the contributors may not be used to endorse or
      promote products derived from this software without specific
      prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Вроде можно брать. Я так понимаю, надо выкинуть 2 и 3 абзацы про что-то там в parser.py, а текст оставшегося LICENSE можно засунуть в питонячий файл, который получится, когда я скопирую их текст класса ленивого файла?

hlebushek ★★
() автор топика
Последнее исправление: hlebushek (всего исправлений: 1)
Ответ на: комментарий от hlebushek

Хотя вообще я посмотрел, и там есть зависимости от другого кода, а там еще от другого. Не хочу все это выковыривать.

hlebushek ★★
() автор топика
Ответ на: комментарий от hlebushek

В нормальном языке программирования я бы использовал какой-нибудь там boost::variant или Either. А как по питонячьи такое сделать?

Ты жалуешься, что в языке с динамической типизацией отсутствует этот ненужный костыль?

if isinstance(something, str):
    ...

proud_anon ★★★★★
()
Ответ на: комментарий от proud_anon

Да, я жалуюсь.

Из документации к функции open:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

file is either a string or bytes object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped. (If a file descriptor is given, it is closed when the returned I/O object is closed, unless closefd is set to False.)

Получается, в file можно передавать не только класс str и его подклассы.

И вдруг у меня будет какой-то класс, который является и файловым объектом, и подклассом str? (какой-нибудь там аналог StringIO например, я пока не уверен, имеет ли это смысл конкретно для str)

hlebushek ★★
() автор топика
Последнее исправление: hlebushek (всего исправлений: 1)

Что мешает открыть файл непосредственно перед записью в него и только в том случае если ты вообще будешь писать в него.

ptah_alexs ★★★★★
()
Ответ на: комментарий от ptah_alexs

Вот-вот. Сначала делай свою проверку, а потом уже решай, открывать файлы или нет.

sanchopanca
()

Например так

class MyFile(object):
  file = None

  def __init__(self, f_name):
    self.f_name = f_name

  def write(self, string):
    if self.file is None:
      self.file = open(self.f_name, "w")
      self.file.write(string)
    else:
      self.file.write(string)

  def close(self):
    if self.file is not None:
      self.file.close

if __name__ == "__main__":
  f1 = MyFile("aaa.txt")
  f2 = MyFile("bbb.txt")
  f1.write("zzz")
  f1.close()
  f2.close()

shy
()
Ответ на: комментарий от hlebushek

Получается, в file можно передавать не только класс str и его подклассы.

Ну ты же сам захотел так сделать: если передавать str или bytes, то открывать его, а в любом другом случае считать, что это файл.

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

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.