Як часто python передається у файл?


228
  1. Як часто Python передає файл?
  2. Як часто Python змивається на вигляд?

Я не впевнений (1).

Що стосується (2), я вважаю, що Python змикається після кожного нового рядка. Але, якщо ви перевантажуєте stdout для файлу, він промітає так часто?

Відповіді:


332

Для файлових операцій Python використовує буферизацію за замовчуванням операційної системи, якщо ви не налаштовуєте це на інше. Ви можете вказати розмір буфера, небуферований або буферний рядок.

Наприклад, відкрита функція приймає аргумент розміру буфера.

http://docs.python.org/library/functions.html#open

"Необов'язковий аргумент буферизації вказує бажаний розмір буфера файлу:"

  • 0 означає незаблокований,
  • 1 означає буферну лінію,
  • будь-яке інше додатне значення означає використання буфера (приблизно) такого розміру.
  • Негативна буферизація означає використовувати системний типовий режим, який зазвичай буферизується для пристроїв tty та повністю буферується для інших файлів.
  • Якщо пропущено, використовується системний замовчування.

код:

bufsize = 0
f = open('file.txt', 'w', buffering=bufsize)

23
+1 для частини "захищена лінія". Це саме те, що я шукав, і це працює як шарм.
відступ

2
Використовуючи Python 3.4.3, коли я роблю, open('file.txt', 'w', 1)я отримую належну буферизацію ліній. Але якщо я роблю щось більше (хотілося open('file.txt', 'w', 512)), воно буферизує повне io.DEFAULT_BUFFER_SIZE8192. Це помилка Python, помилка Linux чи помилка ID10t?
Бруно Броноський

Чи можна змінити буферизацію для вже відкритих потоків? Скажімо, я хочу stdoutбути лінійно захищеним, незалежно від того, чи це консоль чи перенаправлена ​​на файл?
Михайло Т.

1
@CharlieParker, коли ви викликаєте write()ручку файлу, вихід виводиться в пам'ять і накопичується до повного заповнення буфера ... в цей час буфер стає "розмитим" (вміст записується з буфера в файл). Ви можете явно очистити буфер, зателефонувавши flush()методу на файлову ручку.
Корі Голдберг

3
Зауважте, що розблокований (0) доступний лише у двійковому режимі, а буферний рядок (1) доступний лише в текстовому режимі.
ЗайдХ

172

Ви також можете примусити залишити буфер у файл програмно за допомогою flush()методу.

with open('out.log', 'w+') as f:
    f.write('output is ')
    # some work
    s = 'OK.'
    f.write(s)
    f.write('\n')
    f.flush()
    # some other work
    f.write('done\n')
    f.flush()

Я вважаю це корисним під час підключення вихідного файлу до tail -f.


54
З Документів:Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam

1
Наступний раз посилання @bobismijnnaam на вказані документи. Єдине посилання, яке я можу знайти, - це від github.com/jprzywoski/python-reference/blob/master/source/docs/…, і я не знаю, хто це.
Бруно Броноський

5
@Bruno Bronosky Добре. Документи: Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam

те, що мене бентежить, це те, що цей термін flushingнавіть означає. Навіщо нам це потрібно? Для чого це? чому я повинен дбати про це?
Чарлі Паркер

@CharlieParker, коли ви пишете, ви записуєте до копії (частини) файлу в оперативній пам'яті, яка може не зберігатися на диску деякий час. Це підвищує продуктивність, але може означати втрату даних, якщо ця копія ніколи не буде записана (диск видалений, ОС виходить з ладу тощо). flush () повідомляє Python негайно записати цей буфер назад на диск. (Тоді, os.fsync () каже операційній системі також робити це. Є багато шарів буферів ...)
Rena

13

Я не знаю, чи це стосується і python, але я думаю, що це залежить від операційної системи, яку ви працюєте.

Наприклад, в Linux, вихід на термінал змиває буфер в новому рядку, тоді як для виводу у файли він спалахує лише тоді, коли буфер заповнений (за замовчуванням). Це пояснюється тим, що буферизація буде меншою мірою промивати буфер, і користувач менше шансів помітити, якщо вихідний файл не буде змитий на новому рядку у файлі.

Можливо, ви зможете автопромивати висновок, якщо це саме те, що вам потрібно.

EDIT: Я думаю, ви б таким чином автоматично промивали в python (базуючись тут )

#0 means there is no buffer, so all output
#will be auto-flushed
fsock = open('out.log', 'w', 0)
sys.stdout = fsock
#do whatever
fsock.close()

12

Ви також можете перевірити розмір буфера за замовчуванням, зателефонувавши лише з читання атрибута DEFAULT_BUFFER_SIZE з модуля io.

import io
print (io.DEFAULT_BUFFER_SIZE)

1
Дякую! Добре знати, що python встановлює його як ОС, що визначає ... але це допомагає з’ясувати, що попередньо визначає ОС.
Cometsong

2

Ось ще один підхід - до вибору ОП, який саме він віддає перевагу.

Якщо включити наведений нижче код у __init__файл .py перед будь-яким іншим кодом, повідомлення, надруковані разом із printбудь-якими помилками, більше не будуть реєструватися в Log.txt Ableton, а для окремих файлів на вашому диску:

import sys

path = "/Users/#username#"

errorLog = open(path + "/stderr.txt", "w", 1)
errorLog.write("---Starting Error Log---\n")
sys.stderr = errorLog
stdoutLog = open(path + "/stdout.txt", "w", 1)
stdoutLog.write("---Starting Standard Out Log---\n")
sys.stdout = stdoutLog

(для Mac, зміни #username# назву папки користувача. У Windows шлях до папки користувача матиме інший формат)

Коли ви відкриєте файли в текстовому редакторі, який оновлює його вміст, коли файл на диску змінюється (наприклад, для Mac: TextEdit не робить TextWrangler), ви побачите, що журнали оновлюються в режимі реального часу.

Кредити: цей код був скопійований здебільшого із сценаріїв керування поверхнею LiveAPI Натан Рамелла

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.