파이썬에서을 호출하지 않고 파일을 열거 close()
나 파일을 닫지 만 try
– finally
또는 ” with
“문을 사용하지 않으면 이것이 문제입니까? 아니면 파이썬 가비지 수집에 의존하여 모든 파일을 닫는 코딩 연습으로 충분합니까? 예를 들어, 이렇게하는 경우 :
for line in open("filename"):
# ... do stuff ...
… 파일을 닫을 수 없으며 예외로 파일을 닫을 수 없기 때문에 이것이 문제입니까? 또는 for
파일이 범위를 벗어 났기 때문에 진술 의 결론에서 분명히 닫히 겠습니까?
답변
귀하의 예에서 파일은 인터프리터가 종료되기 전에 닫히지 않을 수 있습니다. CPython의 현재 버전에서 CPython은 참조 카운트를 기본 가비지 콜렉션 메커니즘으로 사용하지만 언어의 기능이 아닌 구현 세부 사항이므로 for 루프의 끝에 파일이 닫힙니다. 파이썬의 다른 구현은 이런 식으로 작동한다고 보장되지 않습니다. 예를 들어 IronPython, PyPy 및 Jython은 참조 횟수를 사용하지 않으므로 루프가 끝날 때 파일을 닫지 않습니다.
CPython의 가비지 콜렉션 구현을 사용하는 것은 코드의 이식성을 떨어 뜨리기 때문에 나쁜 습관입니다. CPython을 사용하는 경우 리소스 누수가 없을 수 있지만 참조 계산을 사용하지 않는 Python 구현으로 전환 한 경우 모든 코드를 살펴보고 모든 파일이 올바르게 닫혀 있는지 확인해야합니다.
귀하의 예를 들어 :
with open("filename") as f:
for line in f:
# ... do stuff ...
답변
일부 파이썬은 더 이상 참조되지 않을 때 파일을 자동으로 닫는 반면, 다른 파이썬은 그렇지 않고 파이썬 인터프리터가 종료 될 때 파일을 닫는 것은 O / S에 달려 있습니다.
파일을 닫는 Python의 경우에도 타이밍이 보장되지 않습니다. 즉시 또는 몇 초 / 분 / 시간 / 일이 될 수 있습니다.
따라서 사용중인 Python에서 문제가 발생하지는 않지만 파일을 열어 두는 것은 좋은 습관이 아닙니다. 실제로 cpython 3에서는 파일을 닫지 않았다면 시스템에서 파일을 닫아야한다는 경고가 표시됩니다.
도덕 : 스스로를 정리하십시오. 🙂
답변
이 특별한 경우에 그러한 구조를 사용하는 것이 안전하지만 그러한 관행을 일반화하기위한 몇 가지주의 사항이 있습니다.
- 실행은 파일 디스크립터가 부족할 수 있습니다.
- 일부 시스템 (예 : win32)에서 해당 파일을 삭제하지 못할 수 있습니다
- CPython 이외의 것을 실행하면 파일이 언제 닫히는 지 알 수 없습니다.
- 파일을 쓰기 또는 읽기 / 쓰기 모드로 열면 데이터가 플러시되는 시점을 알 수 없습니다
답변
파일은 가비지 수집되어 닫힙니다. GC는 귀하가 아닌 폐쇄 시점을 결정합니다. 파일 사용을 마치는 즉시 파일을 닫지 않으면 열린 파일 핸들 제한에 도달 할 수 있으므로이 방법은 권장되지 않습니다. for
당신의 루프 내에서 더 많은 파일을 열어두고 남아 있다면 어떨까요?
답변
안녕 동일한 파이썬 스크립트에서 내용을 사용하려고 할 때 파일 설명자를 닫는 것이 매우 중요합니다. 나는 오늘 너무 오래 헥타르 디버깅 후 깨달았습니다. 파일 디스크립터를 닫은 후에 만 내용이 편집 / 제거 / 저장되며 변경 사항이 파일에 영향을주기 때문입니다!
따라서 새 파일에 내용을 쓴 다음 fd를 닫지 않고 내용을 읽는 다른 셸 명령에서 해당 파일 (fd 아님)을 사용하고 있다고 가정합니다. 이 상황에서 예상대로 쉘 명령의 내용을 얻지 못하고 디버그하려고하면 쉽게 버그를 찾을 수 없습니다. 내 블로그 항목 http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html 에서 더 많은 내용을 읽을 수도 있습니다 .
답변
I / O 프로세스 중에 데이터가 버퍼링됩니다. 즉, 파일에 기록되기 전에 임시 위치에 유지됩니다.
파이썬은 버퍼를 플러시하지 않습니다. 즉, 데이터가 파일에 쓰여질 때까지 쓰기가 끝날 때까지 기다립니다. 이를 수행하는 한 가지 방법은 파일을 닫는 것입니다.
닫지 않고 파일에 쓰면 데이터가 대상 파일로 만들지 않습니다.