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


1069

私は慣れています print >>f, "hi there"

ただし、print >>サポートが終了しているようです。上記の行を実行するための推奨される方法は何ですか?

更新:これらのすべての回答について"\n"...これはユニバーサルですか、Unix固有ですか?IE、"\r\n"Windows で実行する必要がありますか?


11
「\ n」はUnix固有ではありません。ファイルがテキストモード(デフォルト)で開かれると、現在のプラットフォームで終了する正しい行に自動的に変換されます。「\ r \ n」を書き込むと、「\ r \ r \ n」が生成されますが、これは誤りです。
D Coetzee 2013年

print ord(os.linesep)ステートメントを追加するだけで、ASCIIコード(ほとんどのUNIXシステムでは10)が表示されます
Stefan Gruenwald

なぜ廃止されたと思いますか?
xxx ---

回答:


1153

これは次のように単純でなければなりません。

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

ドキュメントから:

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

いくつかの有用な読み物:

  • with声明
  • open()
    • 「a」は追加、または使用するためのものです
    • 切り捨てて書き込むには「w」
  • os(特にos.linesep

37
この例は、open / closeの例よりも優れています。を使用withすると、ファイルを閉じることを覚えておくと安全です。
Eyal 2014

18
電話する必要はありませんthe_file.close()か?
フセイン2014年

19
いいえしないでください:stackoverflow.com/questions/3012488/…–
Tal Jerome、

@Johnsyweb投稿の前半で使用を推奨していないのに、なぜ「os.linesep。osにはたくさんの良いものがある!」と言うのですか?私はここで編集を疑っています、そしてそれが反対票の理由かもしれません。
Horse SMith 14

1
@ user3226167:それは興味深い点です。しかし、なぜバイナリファイルを開いてプレーンテキストを書き込むのでしょうか。
Johnsyweb 2017年

961

print()Python 2.6以降で使用可能な関数を使用する必要があります

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

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

別の方法としては、次のものを使用します。

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ドキュメントからの引用:

出力では、改行がNoneの場合、'\n'書き込まれた文字はすべてシステムのデフォルトの行区切り文字に変換されますos.linesep。改行がの場合''、変換は行われません。改行が他の正当な値のいずれかである場合、'\n'書き込まれた文字はすべて、指定された文字列に変換されます。


35
-1「確認したい場合は、文字列に\n"require require newline ="の代わりにos.linesepを追加\r\r\nします。そうしないと、Windowsで発生します。os.linesepで混乱する理由はまったくありません。
John Machin、

7
@ソリン:書き込みモードを追加するための編集はもちろん改善です。ただし、奇妙なことに、os.linesepについては無関心です。私の答えを見てください。ちなみに、引用するドキュメントは3.xのものですが、この部分はテキストモードの2.xにも有効です。書き込まれた「\ n」文字はすべてシステムのデフォルトの行区切り文字os.linesep *に変換されます。 .. Windows:os.linesepの書き込みは、\r\nを含む書き込みと同じです。\nこれはos.linesepに変換される\r\nため、最終結果は\r\r\nです。
John Machin、

7
@ジョンあなたは正しかった、私はos.linesepバグを修正しました。ありがとう。
ソリン、

3
open('myfile','a')代わりにそれを追加しないでopen('myfile','w')ください?
NeDark

6
@BradRudermanこれは、テキストファイルの「行」を構成するPOSIX標準の一部です。つまり、テキストファイルのすべての行は、最後の行も含めて、改行で終了する必要があります。
ウィーラー

116

Pythonのドキュメントには、この方法をお勧めします。

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

したがって、これは私が通常行う方法です:)

docs.python.orgからのステートメント

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


1
withループの内側にネストする必要があるときは、この方法は好きではありません。これにより、ループの進行中は常にファイルを開いたり閉じたりできます。多分私はここで何かを見逃しているのでしょうか、それともこの特定のシナリオでは本当に不利なのでしょうか?
Sibbsギャンブル2016

38
でループするのはどうですか?
j7nn7k 16

fdの行の@ j7nn7k:
momstouch

86

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はと同じ結果を生成しません'\n'。それが同じ結果をもたらすことができる方法はありません。はと同等ですが、'hi there' + os.linesepと同等'hi there\r\n'ではありません'hi there\n'

これは簡単です\n。自動的にos.linesepに変換されるuseです。そして、PythonからWindowsへの最初の移植以来、それは非常に単純なことです。

Windows以外のシステムでos.linesepを使用しても意味がなく、Windowsで誤った結果が生成されます。

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


素晴らしい例-あなたがipythonユーザーなら興味がありますか?セッションをフォーマットするための素晴らしい機能
Alvin

ここで何を伝えようとしているのか完全にはわかりません。os.linesepは、オペレーティングシステムで定義されている行用語文字(または文字列)を返します。Windowsでは、デフォルトで行末に\ r \ nを使用します。ただし、単一の\ nが認識されます。\ nを使用すると完全にポータブルなOUTPUTが得られますが、os.linesepはWindowsでは問題ありません。
Gusdor 2013

5
@Gusdor:ポイントはos.linesep、テキストモードのWindowsで明示的に使用した場合、結果\r\r\nが正しくないということです。「Windowsは...を使用しています」は意味がありません。Cランタイムライブラリ(したがってPython)は、テキストモードでの出力時に変換\n\r\nれます。他のソフトウェアは異なる動作をする場合があります。Windowsで実行されているすべてのソフトウェアが\n、テキストモードで読み取るときに、1つを行区切り文字として認識するわけではありません。Pythonはそうします。Microsoftのメモ帳テキストエディターはサポートしていません。
John Machin

6
間違いなく、あなたではなく、他の誰かがそれを読んでいるでしょう\r。エキストラについてバーフするミッキーマウスソフトウェアがいくつかあります...
John Machin

2
@Gusdorは別の言語からPythonに来ていますか? '\ n'を使用すると、 '\ r \ n'ではなく、ウィンドウに '\ n'が出力されます-つまり、ダムによって期待される '\ r'が不足していますテキストエディター?Johnが言うように、それはPythonの動作ではありません-os.linesepがそうする場合、 '\ n'は自動的に '\ r \ n'に置き換えられます。したがって、ここでos.linesep 明示的に言うの「間違っています」。そのようなDepartment of Redundancy Department。はい、できます。いいえ、したくありません。
ToolmakerSteve

55

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

私は使うだろう:

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

追悼でティム口のうまい人


しかし、OPはファイルに追加のものを書き込みたいと思うかもしれません。ここで、ファイルがwith範囲外になると、ファイルが閉じられます。
キース、

それはなりたいかもしれませんopen(..., 'a')偶数か'at'
mtrw '28年

5
ええと、ええ。それがwithを使うアイデアです。ファイルを開いたままにしたい場合は、最初にopenを呼び出し、完了したらcloseを呼び出します...
Hyperboreus '28年

1
@mtrw。本当です。OPが追加されました。
Hyperboreus、

1
Pythonに関する限り、RIP Tim Toadyです-そして非常に非常に
当然の

21

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

from __future__ import print_function

その後、あなたはします

print("hi there", file=f)

17

大量のデータを書き込んでいて、速度が問題になる場合は、おそらくこれを使用してください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ても、コードが非常に読みやすくなるので、使用することをお勧めします。

更新:このパフォーマンスの違い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")

パフォーマンスの違いは、顕著ではなくなり、平均時間は2.20秒write、3.10秒ですprint。ひとまとまりの文字列を連結してこの大げさな行のパフォーマンスを得る必要がある場合、printより効率的なユースケースは少しまれです。


10

3.5以降ではpathlib、その目的にもを使用できます。

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

テキストモードで指定されたファイルを開き、データを書き込み、ファイルを閉じます。

import pathlib

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

5

Lineとは、「\ n」文字で終わるシリアル化された文字を意味します。行はある時点で最後でなければならないので、各行の終わりで「\ n」を考慮する必要があります。これが解決策です:

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

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

the_file.write("Hello\n")

1
「追加モードでは、書き込みごとにカーソルが新しい行に移動します」–いいえ、そうではありません。
アンセ

3

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

import io
my_string = "hi there"

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

1

フラスコ内のファイルにテキストを書き込むには、次の方法を使用できます。

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

0

あなたも試すことができます 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

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

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

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

更新:としては、言及されたゲオルギーコメントセクションでは、とさらにこのアイデアを向上させることができるpartial機能。

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

私見、これはより機能的で、より不可解なアプローチです。


2
これを書くか、別の(おそらくクリーナー)方法:from functools import partial; fwl = partial(print, file=out)
Georgy

@Georgyあなたのアプローチはとても良いので、新しい答えを出すことができます。
MxNx

1
アイデアはあなたのものと同じですが、実装が少し異なります。必要に応じて、編集内容を回答に追加できます。元気です。
Georgy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.