Подтвердить что ты не робот

Подготовить строку к существующему файлу в Python

Мне нужно добавить одну строку в первую строку текстового файла, и похоже, что для меня доступны только те параметры, которые мне больше подходят, чем ожидалось от python. Что-то вроде этого:

f = open('filename','r')
temp = f.read()
f.close()

f = open('filename', 'w')
f.write("#testfirstline")

f.write(temp)
f.close()

Нет ли более простого способа? Кроме того, я вижу этот пример с двумя дескрипторами чаще, чем открытие одного дескриптора для чтения и записи ( "r +" ) - почему это?

4b9b3361

Ответ 1

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

Основная истина, с которой вы сталкиваетесь, заключается в том, что вы обычно не можете добавлять данные в существующую плоскую структуру, не переписывая всю структуру. Это верно независимо от языка.

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

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

Ответ 2

Я бы придерживался отдельных чтений и писем, но мы, безусловно, можем выразить все более кратко:

python2:

with file('filename', 'r') as original: data = original.read()
with file('filename', 'w') as modified: modified.write("new first line\n" + data)

Python3:

with open('filename', 'r') as original: data = original.read()
with open('filename', 'w') as modified: modified.write("new first line\n" + data)

Примечание: функция file() недоступна в python3.

Ответ 3

Другой подход:

with open("infile") as f1:
    with open("outfile", "w") as f2:
        f2.write("#test firstline")
        for line in f1:
            f2.write(line)

или один лайнер:

open("outfile", "w").write("#test firstline\n" + open("infile").read())

Спасибо за возможность подумать об этой проблеме:)

Приветствия

Ответ 4

with open("file", "r+") as f: s = f.read(); f.seek(0); f.write("prepend\n" + s)

Ответ 5

Вы можете сохранить один вызов записи следующим образом:

f.write('#testfirstline\n' + temp)

При использовании 'r +' вам придется перемотать файл после чтения и перед записью.

Ответ 6

Здесь 3 лайнера, который, я думаю, ясен и гибкий. Он использует функцию list.insert, поэтому, если вы действительно хотите добавить к файлу, используйте l.insert(0, 'insert_str'). Когда я на самом деле сделал это для модуля Python, который я разрабатываю, я использовал l.insert(1, 'insert_str'), потому что я хотел пропустить строку '# -coding: utf-8-' в строке 0. Здесь код.

f = open(file_path, 'r'); s = f.read(); f.close()
l = s.splitlines(); l.insert(0, 'insert_str'); s = '\n'.join(l)
f = open(file_path, 'w'); f.write(s); f.close()

Ответ 7

Самый короткий способ сделать это, сохраняя при этом читаемость:

with open('filename', 'rw') as testfile:
    testfile.writelines(['first line'] + testfile.readlines())

Ответ 8

Выполняет задание, не читая весь файл в памяти, хотя это может не работать в Windows

def prepend_line(path, line):
    with open(path, 'r') as old:
        os.unlink(path)
        with open(path, 'w') as new:
            new.write(str(line) + "\n")
            shutil.copyfileobj(old, new)

Ответ 9

Возможна одна из следующих функций:

import os
open('tempfile', 'w').write('#testfirstline\n' + open('filename', 'r').read())
os.rename('tempfile', 'filename')

Ответ 10

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

def prepend_text(file, text, after=None):
    ''' Prepend file with given raw text '''
    f_read = open(file, 'r')
    buff = f_read.read()
    f_read.close()
    f_write = open(file, 'w')
    inject_pos = 0
    if after:
        pattern = after
        inject_pos = buff.find(pattern)+len(pattern)
    f_write.write(buff[:inject_pos] + text + buff[inject_pos:])
    f_write.close()

Итак, сначала вы открываете файл, читаете его и сохраняете в одной строке. Затем мы попытаемся найти номер символа в строке, где произойдет инъекция. Затем с помощью одной записи и некоторой умной индексации строки мы можем переписать весь файл, включая введенный текст.

Ответ 11

Разве я не вижу что-то или мы не можем просто использовать буфер, достаточно большой, чтобы считывать входной файл по частям (вместо всего содержимого) и с этим буфером проходить по файлу, пока он открыт, и продолжать обмениваться файлом <- > содержимое буфера?

Это кажется гораздо более эффективным (особенно для больших файлов), чем чтение всего содержимого в памяти, изменение его в памяти и запись обратно в тот же файл или (что еще хуже) в другой. Извините, что сейчас у меня нет времени на реализацию примера фрагмента, я вернусь к этому позже, но, возможно, вы поняли идею.