etc./StackOverFlow

파일에 줄을 쓰는 올바른 방법은 무엇입니까?

청렴결백한 만능 재주꾼 2023. 5. 4. 22:14
반응형

질문자 :Yaroslav Bulatov


print >>f, "hi there" 를 하는 데 익숙합니다.

print >> 는 더 이상 사용되지 않는 것 같습니다. 위의 줄을 수행하는 데 권장되는 방법은 무엇입니까?

업데이트 "\n" 이있는 모든 답변과 관련하여 ... 이것이 보편적입니까 아니면 Unix 전용입니까? IE, "\r\n" 을 수행해야 합니까?



이것은 다음과 같이 간단해야 합니다.

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

문서에서:

텍스트 모드(기본값)에서 열린 파일을 작성할 때 os.linesep 를 줄 종결자로 사용하지 마십시오. 모든 플랫폼에서 대신 단일 '\n'을 사용하십시오.

몇 가지 유용한 읽기:


Johnsyweb

Python 2.6 이상부터 사용할 수 print() 함수를 사용해야 합니다.

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

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' 문자가 지정된 문자열로 변환됩니다.


sorin

python 문서 는 다음과 같이 권장합니다.

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

그래서 제가 평소에 하는 방법입니다 :)

docs.python.org의 진술 :

파일 개체를 다룰 때 'with' 키워드를 사용하는 것이 좋습니다. 이것은 도중에 예외가 발생하더라도 스위트가 완료된 후에 파일이 제대로 닫히는 이점이 있습니다. 또한 동등한 try-finally 블록을 작성하는 것보다 훨씬 짧습니다.


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 은 '\n' 과 동일한 결과를 생성 하지 않습니다 . 같은 결과를 낼 수 있는 방법은 없습니다. 'hi there' + os.linesep'hi there\r\n' 과 동일하며 'hi there\n' 과 동일하지 않습니다 .

간단합니다. \n 을 사용하면 자동으로 os.linesep으로 변환됩니다. 그리고 Python을 Windows로 처음 이식한 이후로 매우 간단했습니다.

Windows가 아닌 시스템에서 os.linesep를 사용하는 것은 의미가 없으며 Windows에서 잘못된 결과를 생성합니다.

os.linesep를 사용하지 마십시오!


John Machin

나는 "올바른"방법이 있다고 생각하지 않습니다.

나는 사용할 것입니다 :

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

추모에서 Tim Toady .


Hyperboreus

Python 3에서는 함수이지만 Python 2에서는 소스 파일의 맨 위에 다음을 추가할 수 있습니다.

 from __future__ import print_function

그럼 당신은

 print("hi there", file=f)

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 사용하면 코드를 훨씬 쉽게 읽을 수 있으므로 함께 사용하는 것이 좋습니다.

업데이트 : 이 성능 차이는 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.20s의 평균 시간, 발음된다 write 및 대한 3.10s print . 이 loooong 라인을 얻기 위해 많은 문자열을 연결해야 하는 경우 성능이 저하되므로 print 가 더 효율적인 사용 사례는 약간 드뭅니다.


Robin Keskisarkka

3.5부터 그 목적으로 pathlib 를 사용할 수도 있습니다.

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

텍스트 모드에서 가리키는 파일을 열고 데이터를 쓰고 파일을 닫습니다.

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

johnson

Line이라고 하면 '\n' 문자로 끝나는 직렬화된 문자를 의미합니다. 줄은 특정 지점에서 마지막이어야 하므로 각 줄의 끝에서 '\n'을 고려해야 합니다. 해결책은 다음과 같습니다.

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

각 쓰기 후에 추가 모드에서 커서가 새 줄로 이동합니다. w write() \n 문자를 추가해야 합니다.

 the_file.write("Hello\n")

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)

kmario23

write() 또는 writelines() 사용을 피하고 문자열을 줄 바꿈과 직접 결합하는 print() 에 전달하고 줄 바꿈 구분 기호와 파일 핸들을 키워드 인수로 전달할 수 있습니다. 이 스니펫은 문자열에 후행 줄 바꿈이 없다고 가정합니다.

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

print() 가 자동으로 수행하기 때문에 끝에 특수 개행 문자를 넣을 필요가 없습니다.

목록에 임의의 수의 행이 있는 경우 목록 확장을 사용하여 모든 행을 print() 에 전달할 수 있습니다.

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

"\n" 을 구분 기호로 사용하는 것은 괜찮습니다. print() 도 자동으로 Windows CRLF 줄 바꿈( "\r\n" )으로 변환하기 때문입니다.


Zenul_Abidin

플라스크의 파일에 텍스트를 쓰려면 다음을 사용할 수 있습니다.

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

Sashini Hettiarachchi

행당 형식으로 목록에 항목을 삽입하려는 경우 시작하는 방법은 다음과 같습니다.

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

Alfredo EP

filewriter 를 사용해 볼 수도 있습니다.

pip install filewriter

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

my_file.txt 씁니다.

__str__ 지원하는 객체를 사용합니다.


Emin Bugra Saral

새 줄을 많이 작성해야 할 때 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)

IMHO, 이것은 더 기능적이고 덜 비밀스러운 접근 방식입니다.


MxNx

다른 사람들이 그것을하는 방법에 대해 답변 했으므로 어떻게 발생하는지 한 줄씩 답변하겠습니다.

 with FileOpenerCM('file.txt') as fp: # is equal to "with open('file.txt') as fp:" fp.write('dummy text')

이것은 소위 context manager with 제공되는 모든 것은 컨텍스트 관리자입니다. 이것이 어떻게 내부에서 일어나는지 봅시다.

 class FileOpenerCM: def __init__(self, file, mode='w'): self.file = open(file, mode) def __enter__(self): return self.file def __exit__(self, exc_type, exc_value, exc_traceback): self.file.close()

첫 번째 메서드 __init__ 은 (모두가 알다시피) 객체의 초기화 메서드입니다. 객체가 생성될 때마다 obj.__init__ 이 반드시 호출됩니다. 그리고 그것은 당신이 모든 초기화 코드를 넣는 곳입니다.

두 번째 방법 __enter__ 는 약간 흥미롭습니다. 컨텍스트 관리자를 위한 특정 방법이기 때문에 일부는 보지 못했을 수도 있습니다. as 키워드 뒤에 변수에 할당될 값입니다. 우리의 경우 fp .

마지막 메서드는 오류가 캡처된 후 또는 코드가 with 블록을 종료하는 경우 실행할 메서드입니다. exc_type , exc_value , exc_traceback 변수는 with 블록 내부에서 발생한 에러 값을 담는 변수입니다. 예를 들어,

 exc_type: TypeError exc_value: unsupported operand type(s) for +: 'int' and 'str exc_traceback: <traceback object at 0x6af8ee10bc4d>

처음 두 변수에서 오류에 대한 충분한 정보를 얻을 수 있습니다. 솔직히 세 번째 변수의 용도는 모르지만 저에게는 처음 두 개면 충분합니다. 컨텍스트 관리자에 대해 더 많은 연구를 하고 싶다면 확실히 할 수 있으며 클래스를 작성하는 것이 컨텍스트 관리자를 작성하는 유일한 방법은 아닙니다. contextlib를 사용 하면 함수(실제로 생성기)를 통해 컨텍스트 관리자를 작성할 수도 있습니다. 그것을 보는 것은 전적으로 당신에게 달려 있습니다. 확실히 contextlib로 생성기 기능을 시도할 수 있지만 클래스가 훨씬 깨끗하다는 것을 알 수 있습니다.


Hyperx837

출처 : http:www.stackoverflow.com/questions/6159900/correct-way-to-write-line-to-file

반응형