파이썬에서 파일을 한 줄씩 읽어야합니까?
선사 시대 (Python 1.4)에서 우리는 다음을 수행했습니다.
fp = open('filename.txt')
while 1:
line = fp.readline()
if not line:
break
print line
파이썬 2.1 이후, 우리는 :
for line in open('filename.txt').xreadlines():
print line
파이썬 2.3에서 편리한 반복자 프로토콜을 얻기 전에 다음과 같이 할 수 있습니다.
for line in open('filename.txt'):
print line
좀 더 장황한 예제를 보았습니다.
with open('filename.txt') as fp:
for line in fp:
print line
이것이 선호되는 방법입니까?
[edit] with 문으로 파일을 닫을 수 있지만 파일 객체의 반복자 프로토콜에 포함되지 않은 이유는 무엇입니까?
다음이 선호되는 이유는 정확히 한 가지입니다.
with open('filename.txt') as fp:
for line in fp:
print line
우리는 모두 가비지 콜렉션에 대한 CPython의 비교적 결정적인 참조 계산 체계에 의해 망쳐졌습니다. 다른 가설적인 파이썬의 구현은 with다른 스키마를 사용하여 메모리를 되 찾을 경우 블록 없이 파일을 "빠르게"닫을 필요는 없습니다 .
이러한 구현에서 가비지 수집기가 분리 된 파일 핸들에서 종료자를 호출하는 것보다 코드가 파일을 빠르게 여는 경우 OS에서 "너무 많은 파일이 열렸습니다"오류가 발생할 수 있습니다. 일반적인 해결 방법은 GC를 즉시 트리거하는 것이지만, 이것은 해킹이므로 라이브러리의 오류를 포함하여 오류가 발생할 수있는 모든 기능에 의해 수행되어야합니다 . 악몽이야
아니면 그냥 with블록을 사용할 수도 있습니다 .
보너스 질문
(문제의 객관적인 측면에만 관심이있는 경우 지금 읽기를 중지하십시오.)
파일 객체의 반복자 프로토콜에 왜 포함되어 있지 않습니까?
이것은 API 디자인에 대한 주관적인 질문이므로 두 부분으로 주관적인 답변이 있습니다.
이 반복자 프로토콜은 두 개의 별도의 일을-으로 반복 할 라인을 통해 수 있기 때문에 창자 수준에서, 이것은 잘못된 느낌 과 파일 가까운 핸들과 간단한 보이는 함수는 두 개의 작업을 할 수 있도록하는 것이 좋은 생각입니다. 이 경우 반복자는 파일의 내용과 유사하게 기능적인 값 기반 방식으로 관련되어 있기 때문에 특히 나쁘지만 파일 핸들 관리는 완전히 별개의 작업입니다. 하나의 행동으로 보이지 않게 두 가지를 모두 분류하는 것은 코드를 읽는 사람에게는 놀라운 일이며 프로그램 행동에 대한 추론을 어렵게 만듭니다.
다른 언어들도 본질적으로 같은 결론을 내 렸습니다. Haskell은 이른바 "게으른 IO"로 잠깐 동안 파일을 반복하여 스트림이 끝날 때 자동으로 닫히도록하지만 최근에는 Haskell에서 게으른 IO를 사용하지 않는 것이 일반적으로 바람직하지 않습니다. 사용자는 주로 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 yield from에서이 문장은 이것을 더 짧게 만듭니다 :
def with_iter(iterable):
with iterable as iter:
yield from iter
f = open('test.txt','r')
for line in f.xreadlines():
print line
f.close()
참고 URL : https://stackoverflow.com/questions/11555468/how-should-i-read-a-file-line-by-line-in-python
'Programming' 카테고리의 다른 글
| 명명 규칙-C ++ 및 C # 변수의 밑줄 (0) | 2020.07.03 |
|---|---|
| IHttpActionResult를 반환 할 때 웹 API 작업 방법을 단위 테스트하려면 어떻게합니까? (0) | 2020.07.03 |
| 구성 파일을 사용하는 대신 코드에서 log4net을 구성 할 수 있습니까? (0) | 2020.07.03 |
| 도커 컨테이너에 여러 볼륨을 마운트 하시겠습니까? (0) | 2020.07.03 |
| IsNothing 대 Is Nothing (0) | 2020.07.03 |