Yanıtlar:
Bu sorunun cevabı bir şekilde belirli Python uygulamasına bağlıdır.
Bunun ne hakkında olduğunu anlamak için, gerçek file
nesneye özellikle dikkat edin . Kodunuzda, bu nesne bir ifadede yalnızca bir kez bahsedilir ve read()
çağrı döndükten hemen sonra erişilemez hale gelir .
Bu, dosya nesnesinin çöp olduğu anlamına gelir. Geriye kalan tek soru "Çöp toplayıcı dosya nesnesini ne zaman toplayacak?".
referans sayacı kullanan CPython'da bu tür çöpler hemen fark edilir ve bu yüzden derhal toplanır. Bu genellikle diğer python uygulamaları için geçerli değildir.
Dosyanın kapalı olduğundan emin olmak için daha iyi bir çözüm bu kalıptır:
with open('Path/to/file', 'r') as content_file:
content = content_file.read()
blok bittikten hemen sonra dosyayı her zaman kapatacaktır; bir istisna olsa bile.
Düzenleme: Üzerine daha ince bir nokta koymak için:
Bunun dışında file.__exit__()
"otomatik olarak" Bir de denir, with
bağlam yöneticisi ayarı, sadece başka bir şekilde file.close()
otomatik olarak adlandırılır (açıkça kendiniz çağırarak dışında olduğu,) yoluyladır file.__del__()
. Bu bizi ne zaman __del__()
çağrılır?
Doğru yazılmış bir program, kesinleştiricilerin program sonlandırılmadan önce herhangi bir noktada çalışacağını varsayamaz.
- https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203
Özellikle:
Nesneler asla açıkça yok edilmez; ancak ulaşılamaz hale geldiklerinde çöp toplanabilirler. Bir uygulamanın çöp toplamayı ertelemesine veya tamamen atlamasına izin verilir - hala ulaşılabilen hiçbir nesne toplanmadıkça, çöp toplamasının nasıl uygulandığı bir uygulama kalitesidir.
[...]
CPython şu anda, çoğu nesneyi ulaşılamaz olur olmaz toplayan ancak dairesel referanslar içeren çöpleri toplaması garanti edilmeyen (isteğe bağlı), çevrimsel olarak bağlı çöplerin gecikmeli olarak algılanması ile bir referans sayma şeması kullanmaktadır.
- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types
(Vurgu madeni)
ancak öne sürdüğü gibi, diğer uygulamaların başka davranışları olabilir. Bir örnek olarak, PyPy vardır 6 farklı çöp toplama uygulamalarını !
__exit__()
gibi durumlarda arama yapmamak bir tasarım kusuru gibi geliyor.
try
/ finally
hareketsiz olması ve with
çözen temizleme işleyicilerinin oldukça yaygın kullanımı nedeniyle . "Açık bir şekilde kapanma" ile "yönetme" arasındaki fark with
, bir istisna atılmış olsa bile çıkış işleyicisinin çağrılmasıdır. Bunu close()
bir finally
cümle içine koyabilirsiniz , ancak bunun with
yerine kullanmaktan çok farklı değil, biraz daha karışık (1 yerine 3 ekstra satır) ve doğru elde etmek biraz daha zor.
with foo() as f: [...]
temelde aynıdır f = foo()
, f.__enter__()
[...] ve f.__exit__()
ele istisnalar dışında , böylece __exit__
her zaman denir. Böylece dosya her zaman kapanır.
Pathlib kullanabilirsiniz .
Python 3.5 ve üstü için:
from pathlib import Path
contents = Path(file_path).read_text()
Python'un daha eski sürümleri için pathlib2'yi kullanın :
$ pip install pathlib2
Sonra:
from pathlib2 import Path
contents = Path(file_path).read_text()
Gerçek read_text
uygulama budur :
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()
Dosya içeriğini tek bir dize olarak almak yerine, içeriği dosyanın içerdiği tüm satırların bir listesi olarak saklamak kullanışlı olabilir :
with open('Path/to/file', 'r') as content_file:
content_list = content_file.read().strip().split("\n")
Görüldüğü üzere, tek ihtiyaçları birleştirilmiş yöntemleri eklemek .strip().split("\n")
için bu parçacığı ana cevap .
Burada, .strip()
tüm dosya dizesinin sonundaki boşluk ve satırsonu karakterlerini kaldırır ve dosya dizesinin .split("\n")
tamamını her satırsonu karakterine bölerek gerçek listeyi üretir \ n .
Ayrıca, bu şekilde tüm dosya içeriği, önceki yanıtta belirtildiği gibi dosya satır satır döngü yerine bazı durumlarda istenebilecek bir değişken içinde depolanabilir .