Poprawny sposób zapisu linii do pliku?

Jestem przyzwyczajony do robienia print >>f, "hi there"

Wydaje się jednak, że print >> staje się przestarzały. Jaki jest zalecany sposób wykonania powyższej linii?

Update : Jeśli chodzi o wszystkie odpowiedzi z "\n" ... to jest uniwersalne czy specyficzne dla Uniksa? IE, czy powinienem robić "\r\n" na Windows?

Author: martineau, 2011-05-28

10 answers

To powinno być tak proste jak:

with open('somefile.txt', 'a') as the_file:
    the_file.write('Hello\n')

Z Dokumentacji:

Nie używaj os.linesep jako terminatora linii podczas pisania plików otwartych w trybie tekstowym( domyślnie); używaj jednego "\n " na wszystkich platformach.

Kilka przydatnych lektur:

 744
Author: Johnsyweb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 10:46:58

Powinieneś użyć funkcji print(), która jest dostępna od Pythona 2.6 +

from __future__ import print_function  # Only needed for Python 2
print("hi there", file=f)

W Pythonie 3 nie potrzebujesz import, ponieważ funkcja print() jest domyślna.

Alternatywą byłoby użycie:

f = open('myfile', 'w')
f.write('hi there\n')  # python will convert \n to os.linesep
f.close()  # you can omit in most cases as the destructor will call it

Cytowanie z dokumentacji Pythona odnośnie newlines:

Na wyjściu, jeśli znak nowej linii jest None, wszelkie znaki '\n' są tłumaczone na systemowy domyślny separator linii, os.linesep. Jeśli newline to '', tłumaczenie nie ma miejsca. Jeśli znak nowego wiersza jest którąkolwiek z innych wartości prawnych, to każdy zapisany znak '\n' jest tłumaczony na podany łańcuch.

 911
Author: sorin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-01 21:19:59

The python docs poleca ten sposób:

with open('file_to_write', 'w') as f:
    f.write('file contents')

Więc tak to zwykle robię:)

Wypowiedź z docs.python.org :

Dobrą praktyką jest używanie słowa kluczowego 'with' w przypadku plików obiektów. Ma to tę zaletę, że plik jest poprawnie zamknięty po jego Apartament kończy się, nawet jeśli wyjątek jest podniesiony po drodze. On również znacznie krótsze niż pisanie odpowiedników try-finally blocks.

 95
Author: j7nn7k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-14 13:46:25

Odnośnie os.linesep:

Oto dokładna, nieedytowana sesja interpretera Pythona 2.7.1 w systemie Windows:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.linesep
'\r\n'
>>> f = open('myfile','w')
>>> f.write('hi there\n')
>>> f.write('hi there' + os.linesep) # same result as previous line ?????????
>>> f.close()
>>> open('myfile', 'rb').read()
'hi there\r\nhi there\r\r\n'
>>>

W Systemie Windows:

Zgodnie z oczekiwaniami, os.linesep nie daje takiego samego wyniku jak '\n'. Nie ma możliwości, aby dało to taki sam rezultat. {[2] } jest równoważne 'hi there\r\n', które jest , a nie równoważne 'hi there\n'.

To proste: użyj \n, które zostaną automatycznie przetłumaczone na system operacyjny.linesep. and it ' s been to proste Od pierwszego portu Pythona do Windows.

Nie ma sensu używać systemu operacyjnego.linesep na systemach innych niż Windows i daje błędne wyniki w Windows.

Nie używaj systemu operacyjnego.linesep!

 80
Author: John Machin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-29 03:02:48

Nie sądzę, że istnieje "poprawny"sposób.

Użyłbym:

with open ('myfile', 'a') as f: f.write ('hi there\n')

In memoriam Tim Toady .

 46
Author: Hyperboreus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 05:54:10

W Pythonie 3 jest to funkcja, ale w Pythonie 2 można dodać ją do górnej części pliku źródłowego:

from __future__ import print_function

Potem robisz

print("hi there", file=f)
 17
Author: Keith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 05:49:25

Jeśli piszesz dużo danych, a szybkość jest problemem, powinieneś prawdopodobnie wybrać f.write(...). Zrobiłem szybkie porównanie prędkości i było znacznie szybsze niż print(..., file=f) podczas wykonywania dużej liczby zapisów.

import time    

start = start = time.time()
with open("test.txt", 'w') as f:
    for i in range(10000000):
        # print('This is a speed test', file=f)
        # f.write('This is a speed test\n')
end = time.time()
print(end - start)

Średnio write zakończył się w 2.45 s na mojej maszynie, podczas gdy print trwało około 4 razy dłużej (9.76 s). Biorąc to pod uwagę, w większości realnych scenariuszy nie będzie to problemem.

Jeśli zdecydujesz się iść z print(..., file=f) prawdopodobnie okaże się, że będziesz chciał od czasu do czasu wyłącza znak nowej linii lub zastępuje go czymś innym. Można to zrobić poprzez ustawienie opcjonalnego parametru end, np.;

with open("test", 'w') as f:
    print('Foo1,', file=f, end='')
    print('Foo2,', file=f, end='')
    print('Foo3', file=f)

Cokolwiek wybierzesz, sugeruję użycie with, ponieważ sprawia, że kod jest znacznie łatwiejszy do odczytania.

Update : ta różnica w wydajności jest wyjaśniona przez fakt, że write jest wysoce buforowana i powraca przed jakimkolwiek zapisem na dysk (zobacz ta odpowiedź ), podczas gdy print (prawdopodobnie) używa linii buforowanie. Prostym testem byłoby sprawdzenie wydajności również w przypadku długich zapisów, gdzie wady (pod względem prędkości) buforowania linii byłyby mniej wyraźne.

start = start = time.time()
long_line = 'This is a speed test' * 100
with open("test.txt", 'w') as f:
    for i in range(1000000):
        # print(long_line, file=f)
        # f.write(long_line + '\n')
end = time.time()

print(end - start, "s")
Różnica w wydajności staje się teraz znacznie mniej wyraźna, ze średnim czasem 2,20 s dla write i 3,10 s dla print. Jeśli potrzebujesz połączyć kilka ciągów, aby uzyskać tę linię loooong, wydajność będzie cierpieć, więc przypadki użycia, w których print byłoby bardziej wydajne, są nieco rzadkie.
 14
Author: Robin Keskisarkka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-15 09:17:16

Kiedy powiedziałeś wiersz, oznacza on kilka serializowanych znaków, które kończą się na znaki '\n'. Linia powinna być ostatnia w pewnym momencie, więc powinniśmy rozważyć '\n' na końcu każdej linii. Oto rozwiązanie:

with open('YOURFILE.txt', 'a') as the_file:
    the_file.write('Hello')

W trybie dodawania po każdym zapisie kursor przesuwa się do nowej linii, jeśli chcesz użyć trybu 'w' powinieneś dodać znaki' \n ' na końcu funkcji write ():

the_file.write('Hello'+'\n')
 5
Author: Reza Tanzifi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-26 14:44:36

Od wersji 3.5 możesz również użyć pathlib w tym celu:

Ścieżka.write_text (dane, kodowanie=brak, błędy=Brak)

Otwórz wskazywany plik w trybie tekstowym, Zapisz do niego Dane i zamknij plik:

import pathlib

pathlib.Path('textfile.txt').write_text('content')
 1
Author: johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-11 05:51:53

Można również użyć modułu io Jak w:

import io
my_string = "hi there"

with io.open("output_file.txt", mode='w', encoding='utf-8') as f:
    f.write(my_string)
 0
Author: kmario23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 14:37:20