답변:
이 질문에 대한 대답은 특정 Python 구현에 따라 다릅니다.
이것이 무엇인지 이해하려면 실제 file
물체에 특히주의하십시오 . 코드에서 해당 객체는 표현식에서 한 번만 언급되며 바로 다음에 액세스 할 수 없게됩니다.read()
호출이 반환 된 .
이것은 파일 객체가 쓰레기라는 것을 의미합니다. 남은 유일한 질문은 "가비지 수집기가 언제 파일 개체를 수집합니까?"입니다.
참조 카운터를 사용하는 CPython에서는 이러한 종류의 가비지가 즉시 발견되므로 즉시 수집됩니다. 이것은 일반적으로 다른 파이썬 구현에는 해당되지 않습니다.
파일이 닫히도록하는 더 나은 해결책은 다음 패턴입니다.
with open('Path/to/file', 'r') as content_file:
content = content_file.read()
블록이 끝나 자마자 항상 파일을 닫습니다. 예외가 발생하더라도.
편집 : 그것에 더 좋은 점을 두려면 :
다른보다 file.__exit__()
"자동"는 호출되는, with
상황에 맞는 관리자 설정, 유일한 다른 방법으로 file.close()
자동으로 호출됩니다 (명시 적으로 자신을 호출하는 것보다 다른입니다,)를 통해입니다 file.__del__()
. 이것은 언제 __del__()
전화 를 받느냐에 대한 질문으로 이어집니다 .
올바르게 작성된 프로그램은 종료자가 프로그램 종료 전 어느 시점에서든 실행될 것이라고 가정 할 수 없습니다.
-https : //devblogs.microsoft.com/oldnewthing/20100809-00/ ? p=13203
특히:
객체는 절대 명시 적으로 파괴되지 않습니다. 그러나 도달 할 수 없게되면 가비지 수집 될 수 있습니다. 구현은 가비지 수집을 연기하거나 완전히 생략 할 수 있습니다. 수 있습니다. 여전히 도달 가능한 객체가 수집되지 않는 한 가비지 수집이 구현되는 방식의 구현 품질 문제입니다.
[...]
CPython은 현재 주기적으로 연결된 가비지에 대한 (선택적) 지연 감지와 함께 참조 계산 체계를 사용합니다.이 가비지는 대부분 객체를 도달 할 수 없게되는 즉시 수집하지만 순환 참조가 포함 된 가비지를 수집하는 것은 아닙니다.
-https : //docs.python.org/3.5/reference/datamodel.html#objects-values-and-types
(엠파 시스 마인)
그러나 제안한 것처럼 다른 구현에는 다른 동작이있을 수 있습니다. 예를 들어, PyPy 는 6 개의 서로 다른 가비지 콜렉션 구현을 가지고 있습니다 !
__exit__()
이런 경우에는 전화하지 않는 것이 디자인 결함처럼 들립니다.
try
/ finally
서투른되는 및 정리 처리기의 매우 일반적인 usefulless 그 with
해결한다. "명시 적으로 닫는"과 "관리하는 with
" 의 차이점은 예외가 발생하더라도 종료 핸들러가 호출된다는 것입니다. close()
에 finally
절을 넣을 수는 있지만 with
대신 조금 더 지저분하고 (1 대신 3 줄 추가) 올바르게 사용하는 것이 조금 더 어렵습니다.
with foo() as f: [...]
기본적으로 동일하다 f = foo()
, f.__enter__()
[...]와 f.__exit__()
처리 예외를 제외하고 , 그래서 __exit__
항상라고합니다. 따라서 파일은 항상 닫힙니다.
pathlib 를 사용할 수 있습니다 .
Python 3.5 이상의 경우 :
from pathlib import Path
contents = Path(file_path).read_text()
이전 버전의 Python의 경우 pathlib2를 사용 하십시오 .
$ pip install pathlib2
그때:
from pathlib2 import Path
contents = Path(file_path).read_text()
이것은 실제 read_text
구현입니다 .
def read_text(self, encoding=None, errors=None):
"""
Open the file in text mode, read it, and close the file.
"""
with self.open(mode='r', encoding=encoding, errors=errors) as f:
return f.read()
파일 내용을 단일 문자열로 검색하는 대신 파일을 구성하는 모든 줄의 목록으로 내용 을 저장하는 것이 편리 할 수 있습니다 .
with open('Path/to/file', 'r') as content_file:
content_list = content_file.read().strip().split("\n")
보다시피, 이 스레드의 주요 답변에 연결된 메소드 .strip().split("\n")
를 추가해야합니다 .
여기서는 .strip()
전체 파일 문자열의 끝에서 공백과 개행 문자를 제거 .split("\n")
하고 모든 줄 바꿈 문자 \ n 에서 전체 파일 문자열을 분할하여 실제 목록을 생성합니다 .
또한이 방법으로 전체 파일 내용을 변수에 저장할 수 있습니다 . 이 경우 이전 답변 에서 지적한 것처럼 파일을 한 줄씩 반복하는 대신 일부 경우에 필요할 수 있습니다 .