No Python, se você abrir um arquivo sem chamar close()
ou fechar o arquivo, mas não usar try
- finally
ou a with
instrução " ", isso é um problema? Ou é suficiente, como prática de codificação, confiar na coleta de lixo do Python para fechar todos os arquivos? Por exemplo, se alguém fizer isso:
for line in open("filename"):
# ... do stuff ...
... isso é um problema porque o arquivo nunca pode ser fechado e pode ocorrer uma exceção que impede que seja fechado? Ou será definitivamente fechado na conclusão da for
declaração porque o arquivo está fora do escopo?
python
file
garbage-collection
user553702
fonte
fonte
for
bloco. Sua contagem de referência será zero, fazendo com que ela seja fechada automaticamente, mas apenas funções, classes e módulos definem escopos no Python, não outras instruções compostas.for
blocos e funções / classes / módulos. É muito mais simples que isso: objetos não têm escopos, apenas nomes. Não existe um nome que se refira a esse objeto; portanto, não há nada aqui para permanecer no escopo ou sair do escopo.for
loop e mencionando que o arquivo é fechado por um motivo completamente diferente. Não entra no escopo do Python, pois não é relevante aqui.Respostas:
No seu exemplo, não é garantido que o arquivo seja fechado antes da saída do intérprete. Nas versões atuais do CPython, o arquivo será fechado no final do loop for porque o CPython usa a contagem de referências como seu mecanismo principal de coleta de lixo, mas esse é um detalhe da implementação, não um recurso do idioma. Outras implementações do Python não são garantidas para funcionar dessa maneira. Por exemplo, IronPython, PyPy e Jython não usam contagem de referência e, portanto, não fecham o arquivo no final do loop.
É uma prática recomendada confiar na implementação da coleta de lixo do CPython, pois isso torna seu código menos portátil. Você pode não ter vazamentos de recursos se usar o CPython, mas se alguma vez mudar para uma implementação Python que não usa contagem de referência, precisará passar por todo o seu código e garantir que todos os seus arquivos estejam fechados corretamente.
Para seu exemplo, use:
fonte
with open() as f
fecha automaticamente o arquivo após a conclusão?with
declaração fornece, mas é claro que, para que essa mágica funcione, o objeto deve ter métodos especiais__enter__
e__exit__
, neste último, o objeto fazclose
todas as outras tarefas de limpeza que precisam ser feitas no momento. fim dawith
declaração ...Alguns Pythons fecham arquivos automaticamente quando não são mais referenciados, enquanto outros não, e cabe ao O / S fechar arquivos quando o interpretador Python sair.
Mesmo para os Pythons que fecharão arquivos para você, o tempo não é garantido: pode ser imediatamente ou segundos ou minutos / horas / dias depois.
Portanto, embora você não tenha problemas com o Python que está usando, definitivamente não é uma boa prática deixar seus arquivos abertos. De fato, no cpython 3, você receberá avisos de que o sistema tinha que fechar arquivos para você, se não o fizesse.
Moral: Limpe depois de si mesmo. :)
fonte
Embora seja bastante seguro usar esse construto nesse caso específico, existem algumas ressalvas para generalizar essa prática:
fonte
O arquivo é coletado e, portanto, fechado. O GC determina quando é fechado, não você. Obviamente, essa não é uma prática recomendada, pois você pode atingir o limite de manipulação de arquivos abertos se não fechar os arquivos assim que terminar de usá-los. E se, dentro desse
for
ciclo, você abrir mais arquivos e deixá-los persistentes?fonte
for
instrução - você não precisará esperar pela próxima execução da coleta de lixo.Oi É muito importante fechar o descritor de arquivo na situação em que você usará o conteúdo no mesmo script python. Hoje eu próprio percebo depois de tanto tempo detectando a depuração. O motivo é que o conteúdo será editado / removido / salvo somente depois que você fechar o descritor de arquivo e as alterações forem afetadas no arquivo!
Então, suponha que você tenha a situação de gravar conteúdo em um novo arquivo e, sem fechar o fd, esteja usando esse arquivo (não o fd) em outro comando shell que lê seu conteúdo. Nesta situação, você não obterá o conteúdo do comando shell conforme o esperado e, se você tentar depurar, não poderá encontrar o bug facilmente. você também pode ler mais na minha entrada do blog http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html
fonte
Durante o processo de E / S, os dados são armazenados em buffer: isso significa que eles são mantidos em um local temporário antes de serem gravados no arquivo.
O Python não libera o buffer - isto é, grava dados no arquivo - até ter certeza de que você terminou de escrever. Uma maneira de fazer isso é fechar o arquivo.
Se você gravar em um arquivo sem fechar, os dados não chegarão ao arquivo de destino.
fonte