programing

파이썬에서 파일을 한 줄씩 읽으려면 어떻게 해야 합니까?

stoneblock 2023. 9. 11. 21:26

파이썬에서 파일을 한 줄씩 읽으려면 어떻게 해야 합니까?

선사시대(Python 1.4)에 우리는 다음과 같이 했습니다.

fp = open('filename.txt')
while 1:
    line = fp.readline()
    if not line:
        break
    print(line)

Python 2.1 이후에는 다음과 같은 작업을 수행했습니다.

for line in open('filename.txt').xreadlines():
    print(line)

Python 2.3에서 편리한 반복기 프로토콜을 사용하기 전에 다음 작업을 수행할 수 있었습니다.

for line in open('filename.txt'):
    print(line)

좀 더 장황하게 표현한 예를 몇 가지 봤습니다.

with open('filename.txt') as fp:
    for line in fp:
        print(line)

이것이 앞으로 선호되는 방법입니까?

[edit] 위드 스테이트먼트를 통해 파일을 확실히...파일 개체에 대한 반복기 프로토콜에 포함되지 않는 이유는 무엇입니까?

다음이 선호되는 이유는 정확히 한 가지입니다.

with open('filename.txt') as fp:
    for line in fp:
        print(line)

우리 모두는 쓰레기 수거를 위한 CPython의 비교적 결정론적인 참조 계수 계획에 실망했습니다.그렇지 않으면 Python의 가상 구현이 파일을 "충분히 빨리" 닫아야 하는 것은 아닙니다.with다른 방식을 사용하여 메모리를 회수하는 경우 차단합니다.

이러한 구현에서 코드가 가비지 콜렉터가 고아 파일 핸들의 최종화자를 호출하는 것보다 빨리 파일을 열면 OS에서 "너무 많은 파일이 열려 있습니다"라는 오류가 발생할 수 있습니다.일반적인 해결 방법은 GC를 즉시 트리거하는 것이지만, 이것은 고약한 해킹이며 라이브러리에 있는 것을 포함하여 오류가 발생할 수 있는 모든 기능에 의해 수행되어야 합니다.정말 악몽같군요.

아니면 그냥 당신이 사용할 수 있습니다.with막다른 골목

보너스 질문

(문제의 객관적인 측면에만 관심이 있는 경우 지금 읽기를 중지합니다.)

파일 개체에 대한 반복기 프로토콜에 포함되지 않는 이유는 무엇입니까?

API 설계에 대한 주관적인 질문이라 두 부분으로 나누어 주관적인 답변을 드립니다.

반복기 프로토콜이 을 통해 반복하고 파일 핸들을 닫는 두 가지 개별적인 작업을 수행하도록 만들기 때문에 일반적으로 단순해 보이는 기능이 두 가지 작업을 수행하도록 하는 것은 좋지 않은 생각입니다.이 경우 반복자가 파일 내용에 준기능적인 값 기반 방식으로 관련되기 때문에 특히 기분이 나쁘지만 파일 핸들 관리는 완전히 별개의 작업입니다.두 가지 모두를 눈에 보이지 않게 하나의 행동으로 으깨는 것은 코드를 읽는 사람들에게는 놀라운 일이며 프로그램 행동에 대한 추론을 더욱 어렵게 만듭니다.

다른 언어들도 본질적으로 같은 결론에 도달했습니다.Haskell은 파일을 반복하고 스트림 끝에 도달하면 자동으로 닫히는 이른바 "게으른 IO"에 잠시 추파를 던졌지만, 요즘 Haskell에서 게으른 IO를 사용하는 것은 거의 보편적으로 권장되지 않습니다.그리고 Haskell 사용자들은 대부분 Conduit와 같은 더 명백한 리소스 관리로 이동했습니다. Conduit와 더 유사하게 행동합니다.withPython에서 블록합니다.

기술적인 차원에서 파이썬의 파일 핸들을 반복해서 닫으면 파일 핸들도 작동하지 않는 몇 가지 작업을 수행할 수 있습니다.예를 들어, 파일을 두 번 반복해야 한다고 가정해 보겠습니다.

with open('filename.txt') as fp:
    for line in fp:
        ...
    fp.seek(0)
    for line in fp:
        ...

이것은 덜 일반적인 사용 사례이지만, 제가 원래 상위 세 줄을 가지고 있던 기존 코드 베이스에 하단의 세 줄의 코드를 추가했을 수도 있다는 사실을 생각해보세요.반복이 파일을 닫으면 저는 그렇게 할 수 없습니다.따라서 반복과 리소스 관리를 분리하여 유지하면 코드 덩어리를 더 크고 작동하는 Python 프로그램으로 쉽게 구성할 수 있습니다.

합성성은 언어나 API의 가장 중요한 사용성 기능 중 하나입니다.

네.

with open('filename.txt') as fp:
    for line in fp:
        print(line)

가야 할 길입니다.

그것은 더 장황하지 않습니다.그것은 더 안전합니다.

추가 줄로 꺼지면 다음과 같은 래퍼 기능을 사용할 수 있습니다.

def with_iter(iterable):
    with iterable as iter:
        for item in iter:
            yield item

for line in with_iter(open('...')):
    ...

3에서 파이썬 3.3은yield from성명을 통해 이를 더욱 단축할 수 있습니다.

def with_iter(iterable):
    with iterable as iter:
        yield from iter

언급URL : https://stackoverflow.com/questions/11555468/how-should-i-read-a-file-line-by-line-in-python