Python bir dosyaya ne sıklıkla akar?


228
  1. Python bir dosyaya ne sıklıkla akar?
  2. Python stdout'a ne sıklıkla akar?

Emin değilim (1).

(2) 'e gelince, Python'un her yeni çizgiden sonra stdout atması gerektiğine inanıyorum. Ancak, stdout'u bir dosyaya yüklemek için aşırı yüklerseniz, sık sık temizlenir mi?

Yanıtlar:


332

Dosya işlemleri için, aksi belirtilmedikçe işletim sisteminin varsayılan arabelleğini kullanır. Arabelleğe alınmış veya arabelleğe alınmış bir satır boyutu belirtebilirsiniz.

Örneğin, open işlevi bir arabellek boyutu bağımsız değişkeni alır.

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

"İsteğe bağlı arabelleğe alma bağımsız değişkeni, dosyanın istenen arabellek boyutunu belirtir:"

  • 0 arabelleksiz anlamına gelir,
  • 1, tamponlanmış satır anlamına gelir,
  • diğer herhangi bir pozitif değer, bu boyutta (yaklaşık olarak) bir tampon kullanılması anlamına gelir.
  • Negatif bir arabelleğe alma, varsayılan olarak tty aygıtları için satır arabelleğe alınan ve diğer dosyalar için tamamen arabelleğe alınan sistem varsayılanını kullanmak anlamına gelir.
  • Atlanırsa, sistem varsayılanı kullanılır.

kod:

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

23
"Satır arabelleğe alınan" bölüm için +1. Tam da aradığım şey buydu ve bir cazibe gibi çalışıyor.
dizginlemek

2
Python 3.4.3'ü kullandığımda open('file.txt', 'w', 1)doğru satır arabelleğe almayı alıyorum. Ama daha büyük bir şey yaparsam (istedim open('file.txt', 'w', 512)) io.DEFAULT_BUFFER_SIZE8192 dolu tamponlar. Bu bir Python hata, Linux hata veya ID10t hata mı?
Bruno Bronosky

Önceden açılmış akışlar için arabelleğe almayı değiştirmek mümkün müdür ? Diyelim ki, stdoutister konsol olsun ister bir dosyaya yönlendirilsin, satır arabelleğe alınsın mı?
Mikhail T.

1
@CharlieParker write()bir dosya tanıtıcısını çağırdığınızda , çıktı bellekte arabelleğe alınır ve arabellek dolana kadar birikir ... bu sırada arabellek "temizlenir" (içerik arabellekten dosyaya yazılır). flush()Bir dosya tanıtıcısında yöntemi çağırarak arabelleği açıkça temizleyebilirsiniz .
Corey Goldberg

3
Arabelleğe alınmamış (0) yalnızca ikili modda ve satır arabelleğe alınmış (1) yalnızca metin modunda kullanılabilir.
ZeydH

173

Ayrıca, yöntemle arabelleği programlı olarak bir dosyaya akıtmaya zorlayabilirsiniz 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()

Bir çıktı dosyası ile kuyruklarken bu yararlı buldum tail -f.


54
Dokümanlar'dan: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 bir dahaki sefere adı geçen dokümanlara bağlantı. Bulabildiğim tek referans github.com/jprzywoski/python-reference/blob/master/source/docs/… ve referansın kim olduğunu bilmiyorum.
Bruno Bronosky

5
@Bruno Bronosky İyi bir nokta. Dokümanlar: Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam

kafam karıştı, terimin ne flushinganlama geldiği. Neden ihtiyacımız var? Bu ne için? neden umursamalıyım?
Charlie Parker

@CharlieParker yazdığınızda, dosyanın bir kısmının (bir kısmının) RAM'de bir süreliğine kaydedilemeyen bir kopyasını yazarsınız. Performansı artırır, ancak bu kopya asla yazılmazsa (disk kaldırılır, işletim sistemi çöküyor, vb.) Veri kaybı anlamına gelebilir. flush (), Python'a bu arabelleği hemen diske yazmasını söyler. (Sonra, os.fsync () işletim sistemine bunu yapmasını söyler. Çok sayıda tampon katmanı vardır ...)
Rena

13

Bunun python için de geçerli olup olmadığını bilmiyorum, ancak çalıştırdığınız işletim sistemine bağlı olduğunu düşünüyorum.

Örneğin Linux'ta terminale çıktı, yeni satırda arabelleği temizlerken, dosyalara çıktı için ise yalnızca tampon dolduğunda temizlenir (varsayılan olarak). Bunun nedeni, arabelleği daha az kez yıkamanın daha verimli olması ve kullanıcının çıktının bir dosyadaki yeni satırda yıkanmadığını fark etmesinin daha az olası olmasıdır.

İhtiyacınız olan şey buysa çıktıyı otomatik olarak yıkayabilirsiniz.

EDIT: Bence bu şekilde python otomatik olarak yıkayın ( buradan dayalı )

#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

İo modülünden salt okunur DEFAULT_BUFFER_SIZE özniteliğini çağırarak varsayılan arabellek boyutunu da kontrol edebilirsiniz.

import io
print (io.DEFAULT_BUFFER_SIZE)

1
Teşekkürler! It iyidir bilmek o OS tanımlayıp olarak piton setleri bunu ... ama şuna bulmanıza yardımcı neyi OS tanımlarınızı öncesi.
Mart'ta Cometsong

2

İşte OP'ye kadar hangisini tercih ettiğini seçmek için başka bir yaklaşım.

Aşağıdaki kodu __init__başka bir koddan önce .py dosyasına printeklediğinizde , yazdırılan iletiler ve hatalar artık Ableton'un Log.txt dosyasına kaydedilmeyecek, ancak diskinizdeki dosyaları ayırmak için:

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#için kullanıcı klasörünüzün adını değiştirin . Windows'ta kullanıcı klasörünüzün yolu farklı bir biçime sahip olacaktır)

Diskteki dosya değiştirildiğinde içeriği yenileyen bir metin düzenleyicide dosyaları açtığınızda (Mac için örnek: TextEdit yapmaz ancak TextWrangler bunu yapar), günlüklerin gerçek zamanlı olarak güncellendiğini göreceksiniz.

Kredi: Bu kod çoğunlukla Nathan Ramella tarafından liveAPI kontrol yüzeyi komut dosyalarından kopyalandı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.