Correcte manier om regel naar bestand te schrijven?

Ik ben gewend om print >>f, "hi there"

te doen

Het lijkt er echter op dat print >>verouderd raakt. Wat is de aanbevolen manier om de bovenstaande regel te doen?

Bijwerken:
Wat betreft al die antwoorden met "\n"…is dit universeel of Unix-specifiek? IE, moet ik "\r\n"op Windows doen?


Antwoord 1, autoriteit 100%

Dit zou zo simpel moeten zijn als:

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

Uit de documentatie:

Gebruik os.linesepniet als regelterminator bij het schrijven van bestanden die in tekstmodus zijn geopend (de standaardinstelling); gebruik in plaats daarvan een enkele ‘\n’ op alle platforms.

Nuttig leesvoer:


Antwoord 2, autoriteit 73%

U moet de functie print()gebruiken die beschikbaar is sinds Python 2.6+

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

Voor Python 3 heb je niet de import, omdat de print()Functie de standaard is.

Het alternatief zou zijn om te gebruiken:

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

citeren van Python-documentatie met betrekking tot newlines:

Aan de uitgang, als NEWLINE geen is, elke '\n'tekens geschreven worden vertaald naar de standaardlijnafscheider van het systeem, os.linesep. Als Newline ''is, vindt er geen vertaling plaats. Als Newline een van de andere wettelijke waarden is, worden elke '\n'tekens geschreven, vertaald naar de gegeven string.


3, Autoriteit 9%

De python docs Beveel op deze manier:

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

Dus dit is de manier waarop ik het meestal doe 🙂

Verklaring van docs.python.org :

Het is een goede gewoonte om de ‘met’ trefwoord te gebruiken bij het omgaan met bestand
voorwerpen. Dit heeft het voordeel dat het bestand correct is gesloten na
De suite eindigt, zelfs als er onderweg een uitzondering wordt opgehaald. Het is
Ook veel korter dan het schrijven van equivalent try-eindelijk blokken.


4, Autoriteit 7%

over OS.LINESEP:

Hier is een exacte niet-aangedreven Python 2.7.1-tolk sessie op 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'
>>>

Op Windows:

Zoals verwacht levert os.linesep NIEThetzelfde resultaat op als '\n'. Er is geen manier dat het hetzelfde resultaat zou kunnen opleveren. 'hi there' + os.linesepis gelijk aan 'hi there\r\n', wat NIETgelijk is aan 'hi there\n'.

Het is zo simpel: gebruik \ndie automatisch wordt vertaald naar os.linesep.En zo eenvoudig is het geweest sinds de eerste poort van Python naar Windows.

Het heeft geen zin om os.linesep te gebruiken op niet-Windows-systemen, en het geeft verkeerde resultaten op Windows.

GEBRUIK GEEN os.linesep!


Antwoord 5, autoriteit 4%

Ik denk niet dat er een “juiste” manier is.

Ik zou gebruiken:

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

In memoriam Tim Toady.


Antwoord 6, autoriteit 2%

In Python 3 is het een functie, maar in Python 2 kun je dit bovenaan het bronbestand toevoegen:

from __future__ import print_function

Dan doe je

print("hi there", file=f)

Antwoord 7

Als u veel gegevens schrijft en snelheid een probleem is, moet u waarschijnlijk f.write(...)gebruiken. Ik deed een snelle snelheidsvergelijking en het was aanzienlijk sneller dan print(..., file=f)bij het uitvoeren van een groot aantal schrijfbewerkingen.

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)

Gemiddeld eindigde writein 2,45 seconden op mijn computer, terwijl printongeveer 4 keer zo lang duurde (9,76 seconden). Dat gezegd hebbende, zal dit in de meeste real-world scenario’s geen probleem zijn.

Als u ervoor kiest om print(..., file=f)te gebruiken, zult u waarschijnlijk merken dat u de nieuwe regel van tijd tot tijd wilt onderdrukken, of deze wilt vervangen door iets anders . Dit kan worden gedaan door de optionele parameter endin te stellen, bijvoorbeeld;

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

Welke manier je ook kiest, ik raad aan om withte gebruiken, omdat het de code veel gemakkelijker te lezen maakt.

Update: dit prestatieverschil wordt verklaard door het feit dat writesterk wordt gebufferd en terugkeert voordat er daadwerkelijk naar schijf wordt geschreven (zie dit antwoord), terwijl printgebruikt (waarschijnlijk) lijnbuffering. Een eenvoudige test hiervoor zou zijn om ook de prestaties voor lange schrijfbewerkingen te controleren, waarbij de nadelen (in termen van snelheid) voor lijnbuffering minder uitgesproken zouden zijn.

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

Het prestatieverschil wordt nu veel minder uitgesproken, met een gemiddelde tijd van 2,20s voor writeen 3,10s voor print. Als je een aantal strings moet aaneenschakelen om deze lange lijn te krijgen, zal de prestatie eronder lijden, dus use-cases waarbij printefficiënter zou zijn, zijn een beetje zeldzaam.


Antwoord 8

Sinds 3.5 kun je ook de pathlibvoor dat doel:

Path.write_text(data, encoding=None, errors=None)

Open het bestand waarnaar in de tekstmodus wordt verwezen, schrijf er gegevens naar en sluit het bestand:

import pathlib
pathlib.Path('textfile.txt').write_text('content')

9

Men kan ook de io-module gebruiken als in:

import io
my_string = "hi there"
with io.open("output_file.txt", mode='w', encoding='utf-8') as f:
    f.write(my_string)

10

Om tekst in een bestand in de kolf te schrijven, kan worden gebruikt:

filehandle = open("text.txt", "w")
filebuffer = ["hi","welcome","yes yes welcome"]
filehandle.writelines(filebuffer)
filehandle.close()

11

Als u wilt vermijden met behulp van write()of writelines()en toetreding van de snaren met een nieuwlijn zelf, kunt u al uw regels doorgeven aan print(), en de Newline-scheidingsteken en uw bestandhandvat als trefwoordargumenten. Dit fragment veronderstelt dat je snaren geen trailing newlines hebben.

print(line1, line2, sep="\n", file=f)

U hoeft niet een speciaal nieuwlijnteken te plaatsen is aan het einde nodig, omdat print()voor u doet.

Als u een willekeurig aantal regels in een lijst hebt, kunt u lijstuitbreiding gebruiken om ze allemaal door te geven aan print().

lines = ["The Quick Brown Fox", "Lorem Ipsum"]
print(*lines, sep="\n", file=f)

Het is OK om "\n"te gebruiken als de separator op Windows, omdat print()automatisch automatisch naar een Windows CRLF-newline ("\r\n").


12

Als u items in een lijst met een indeling per regel wilt invoegen, kan een manier om te starten:

with open('somefile.txt', 'a') as the_file:
    for item in items:
        the_file.write(f"{item}\n")

13

U kunt ook proberen filewriter

pip install filewriter

from filewriter import Writer
Writer(filename='my_file', ext='txt') << ["row 1 hi there", "row 2"]

Schrijft in my_file.txt

neemt een taak of een object met __str__ondersteuning.


14

Als ik veel nieuwe regels moet schrijven, definieer ik een lambda die een printFunctie gebruikt:

out = open(file_name, 'w')
fwl = lambda *x, **y: print(*x, **y, file=out) # FileWriteLine
fwl('Hi')

Deze aanpak heeft het voordeel dat het alle functies kan gebruiken die beschikbaar zijn met de print-functie.

Update: Zoals wordt vermeld door georgy in het gedeelte Opmerkingen, is het mogelijk Verbeter dit idee verder met de partialfunctie:

from functools import partial
fwl = partial(print, file=out)

IMHO, dit is een meer functionele en minder cryptische benadering.

Other episodes