À quelle fréquence python vide-t-il un fichier?

228
  1. À quelle fréquence Python vide-t-il un fichier?
  2. À quelle fréquence Python passe-t-il à la sortie standard?

Je ne suis pas sûr de (1).

En ce qui concerne (2), je crois que Python se vide à stdout après chaque nouvelle ligne. Mais, si vous surchargez stdout pour être dans un fichier, est-il vidé aussi souvent?

Tim McJilton
la source

Réponses:

332

Pour les opérations sur les fichiers, Python utilise la mise en mémoire tampon par défaut du système d'exploitation, sauf si vous le configurez autrement. Vous pouvez spécifier une taille de tampon, non tamponnée ou une ligne tamponnée.

Par exemple, la fonction open prend un argument de taille de tampon.

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

"L'argument de mise en mémoire tampon facultatif spécifie la taille de mémoire tampon souhaitée du fichier:"

  • 0 signifie non tamponné,
  • 1 signifie ligne mise en mémoire tampon,
  • toute autre valeur positive signifie utiliser un tampon de (approximativement) cette taille.
  • Une mise en mémoire tampon négative signifie utiliser la valeur par défaut du système, qui est généralement mise en mémoire tampon de ligne pour les périphériques tty et entièrement mise en mémoire tampon pour les autres fichiers.
  • S'il est omis, la valeur par défaut du système est utilisée.

code:

bufsize = 0
f = open('file.txt', 'w', buffering=bufsize)
Corey Goldberg
la source
23
+1 pour la partie "ligne tamponnée". C'est exactement ce que je cherchais et cela fonctionne comme un charme.
rênes
2
En utilisant Python 3.4.3 quand je le fais, open('file.txt', 'w', 1)j'obtiens un tampon de ligne approprié. Mais si je fais quelque chose de plus grand (je le voulais open('file.txt', 'w', 512)), il tamponne le plein io.DEFAULT_BUFFER_SIZEde 8192. Est-ce un bogue Python, un bogue Linux ou un bogue ID10t?
Bruno Bronosky du
Est-il possible de modifier la mise en mémoire tampon des flux déjà ouverts ? Dis, je veux stdoutêtre mis en mémoire tampon, que ce soit une console ou redirigé vers un fichier?
Mikhail T.
1
@CharlieParker lorsque vous appelez write()un descripteur de fichier, la sortie est mise en mémoire tampon et accumulée jusqu'à ce que le tampon soit plein ... auquel moment le tampon est "vidé" (le contenu est écrit du tampon dans le fichier). Vous pouvez vider explicitement le tampon en appelant la flush()méthode sur un descripteur de fichier.
Corey Goldberg
3
Notez que non tamponné (0) n'est disponible qu'en mode binaire et que la ligne tamponnée (1) n'est disponible qu'en mode texte.
ZaydH
173

Vous pouvez également forcer le vidage du tampon dans un fichier par programme avec la flush()méthode.

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()

J'ai trouvé cela utile lors de la personnalisation d'un fichier de sortie avec tail -f.

kortina
la source
54
De la documentation: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 la prochaine fois un lien vers lesdits documents. La seule référence que je peux trouver provient de github.com/jprzywoski/python-reference/blob/master/source/docs/… et je ne sais pas qui c'est.
Bruno Bronosky
5
@Bruno Bronosky Bon point. Docs: Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam
ce que je suis confus est ce que le terme flushingsignifie même. Pourquoi en avons-nous besoin? Pourquoi est-ce? pourquoi devrais-je m'en soucier?
Charlie Parker
@CharlieParker lorsque vous écrivez, vous écrivez sur une copie (d'une partie) du fichier en RAM, qui pourrait ne pas être enregistrée sur le disque pendant un certain temps. Il améliore les performances, mais peut entraîner une perte de données si cette copie n'est jamais écrite (disque supprimé, système d'exploitation se bloque, etc.). flush () indique à Python de réécrire immédiatement ce tampon sur le disque. (Ensuite, os.fsync () indique au système d'exploitation de le faire également. Il existe de nombreuses couches de tampons ...)
Rena
13

Je ne sais pas si cela s'applique également à python, mais je pense que cela dépend du système d'exploitation que vous utilisez.

Sous Linux par exemple, la sortie vers le terminal vide le tampon sur une nouvelle ligne, tandis que pour la sortie vers les fichiers, elle ne vide que lorsque le tampon est plein (par défaut). En effet, il est plus efficace de vider le tampon moins de fois et l'utilisateur est moins susceptible de remarquer si la sortie n'est pas vidée sur une nouvelle ligne dans un fichier.

Vous pourrez peut-être vider automatiquement la sortie si c'est ce dont vous avez besoin.

EDIT: Je pense que vous viderez automatiquement en python de cette façon (basé à partir d' ici )

#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()
KLee1
la source
12

Vous pouvez également vérifier la taille de la mémoire tampon par défaut en appelant l'attribut en lecture seule DEFAULT_BUFFER_SIZE à partir du module io.

import io
print (io.DEFAULT_BUFFER_SIZE)
N Randhawa
la source
1
Merci! Il est bon de savoir que python le définit comme le système d'exploitation définit ... mais cela permet de savoir ce que le système d'exploitation prédéfinit.
Cometsong
2

Voici une autre approche, jusqu'au PO pour choisir celle qu'il préfère.

Lorsque vous incluez le code ci-dessous dans le __init__fichier .py avant tout autre code, les messages imprimés printet les erreurs ne seront plus enregistrés dans Ableton's Log.txt mais pour séparer les fichiers sur votre disque:

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

(pour Mac, changez #username# le nom de votre dossier utilisateur. Sous Windows, le chemin d'accès à votre dossier utilisateur aura un format différent)

Lorsque vous ouvrez les fichiers dans un éditeur de texte qui actualise son contenu lorsque le fichier sur le disque est modifié (exemple pour Mac: TextEdit ne le fait pas, mais TextWrangler le fait), vous verrez les journaux mis à jour en temps réel.

Crédits: ce code a été copié principalement à partir des scripts de surface de contrôle liveAPI par Nathan Ramella

Mattijs
la source