web-dev-qa-db-ja.com

ファイルに行を書き込むための正しい方法は?

私はprint >>f, "hi there"をやっています

しかし、print >>は非推奨になりつつあるようです。上記の行を実行するための推奨される方法は何ですか?

更新"\n"...を使ったこれらすべての答えに関して、これは一般的なものですか、それともUnix固有のものですか? IE、私はWindowsで"\r\n"をするべきですか?

897

これは以下のように単純なはずです。

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

ドキュメントから:

テキストモード(デフォルト)で開かれたファイルを書くとき、os.linesepをラインターミネータとして使用しないでください。すべてのプラットフォームで、代わりに単一の '\ n'を使用してください。

いくつかの便利な読書:

881
Johnsyweb

Python 2.6以降で利用可能なprint()関数を使うべきです。

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

Python 3では、print()関数がデフォルトなので、importは必要ありません。

代替手段は次のようになります。

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

Pythonドキュメント からの改行に関する引用

NewlineがNoneの場合、出力時には、書き込まれた'\n'文字はシステムのデフォルトの行区切り文字os.linesepに変換されます。改行が''の場合、翻訳は行われません。改行が他の有効な値のいずれかである場合、書かれた'\n'文字は与えられた文字列に翻訳されます。

936
sorin

pythonドキュメント この方法をお勧めします:

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

だからこれは私が通常それを行う方法です:)

docs.python.org :からの声明

ファイルオブジェクトを扱うときは、 'with' キーワードを使用することをお勧めします。これは、たとえ途中で例外が発生したとしても、スイートが終了した後にファイルが適切に閉じられるという利点があります。同等のtry-finallyブロックを書くよりもはるかに短いです。

104
j7nn7k

os.linesep:について

これは、Windows上でのPython 2.7.1の未確認のインタプリタセッションです。

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'
>>>

Windowsの場合

予想通り、os.linesepはNOTを実行しても'\n'と同じ結果になります。それが同じ結果を生み出すことができる方法はありません。 'hi there' + os.linesep'hi there\r\n'と等価です。これはNOT'hi there\n'と等価であることを意味します。

これは簡単です。自動的にos.linesepに翻訳される\nを使用してください。そして、PythonがWindowsに最初に移植されて以来ずっと簡単です。

Windows以外のシステムでos.linesepを使用しても意味がありません。また、Windowsでは誤った結果が生じます。

os.linesepを使用しないでください!

85
John Machin

「正しい」方法はないと思います。

私は使うだろう:

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

メモリアムで Tim Toady

52
Hyperboreus

Python 3ではこれは関数ですが、Python 2ではこれをソースファイルの先頭に追加することができます。

from __future__ import print_function

それからあなたは

print("hi there", file=f)
20
Keith

大量のデータを書き込み、速度が懸念される場合は、おそらくf.write(...)を使用する必要があります。迅速な速度比較を行いましたが、大量の書き込みを実行する場合、print(..., file=f)よりもかなり高速でした。

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)

私のマシンでは平均してwriteは2.45秒で終了しましたが、printは約4倍の時間(9.76秒)でした。とはいえ、ほとんどの実際のシナリオでは、これは問題になりません。

print(..., file=f)を使用することを選択した場合、おそらく、改行を時々抑制したり、何か別のものに置き換えたりすることができます。これは、オプションのendパラメーターを設定することで実行できます。

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

どちらの方法を選択しても、コードを読みやすくするため、withを使用することをお勧めします。

Update:このパフォーマンスの違いは、writeが高度にバッファリングされ、ディスクへの書き込みが実際に行われる前に戻るという事実によって説明されます(参照 この答え )。一方、printは(おそらく)行バッファリングを使用します。このための簡単なテストは、長時間の書き込みのパフォーマンスもチェックすることです。この場合、ラインバッファリングの欠点(速度の面)はそれほど顕著ではありません。

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

パフォーマンスの違いは、writeの平均時間が2.20秒で、printの平均時間が3.10秒で、それほど顕著ではなくなりました。この長い行のパフォーマンスを得るために一連の文字列を連結する必要がある場合、printの方が効率的なユースケースは少しまれです。

16

3.5以降では、 pathlib を使用することもできます。

Path.write_text(データ、エンコーディング=なし、エラー=なし)

ポイントしたファイルをテキストモードで開き、データを書き込み、ファイルを閉じます。

import pathlib

pathlib.Path('textfile.txt').write_text('content')
8
johnson

あなたが行を言ったとき、それは '\ n'文字で終わるいくつかの直列化された文字を意味します。行はある時点で最後になるはずなので、各行の終わりに '\ n'を考えるべきです。これが解決策です。

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

追加モードでは、毎回カーソルを新しい行に移動します。 'w'モードを使用したい場合は、write()関数の最後に '\ n'文字を追加する必要があります。

the_file.write('Hello'+'\n')
4
Reza Tanzifi

次のようにioモジュールを使うこともできます。

import io
my_string = "hi there"

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

新しい行をたくさん書く必要があるとき、print関数を使用するラムダを定義します。

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

このアプローチには、print関数で使用可能なすべての機能を利用できるという利点があります。

更新:コメントセクションで Georgy で言及されているように、partial 関数:

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

私見、これはより機能的でわかりにくいアプローチです。

0
MxNx

filewriterを試すこともできます

pip install filewriter

from filewriter import Writer

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

my_file.txtに書き込みます

イテレート可能オブジェクトまたは__str__サポート付きのオブジェクトを受け取ります。

0