Python'da bir dosyaların listesi nasıl açılır?

Veri dosyasını okuyorum (metin) ve birkaç rapor üretiyorum, her biri farklı bir çıktı dosyasına (ayrıca metin) yazılıyor. Onlara uzun yol açıyorum:

fP = açık ('dosya1', 'w')

invP = açık ('envanter', 'w')

orderP = açık ('siparişler', 'w')

... ve benzerleri, sonunda bir karşılık gelen close() satır grubuyla.

Onları bir for döngüsü ile açabilirsem, fP adlarının ve dosya adlarının bir listesini kullanarak aynı dosyaları kapatmayı garanti edebilirim.

fp: filename sözlüğünü kullanmayı denedim, ancak fP değişkeni tanımsız olduğundan veya 'fP' dizgisi iyi bir dosya nesnesi adı olmadığından [açıkça] işe yaramadı.

Bunlar çıktı dosyaları olduğundan muhtemelen açık hataları kontrol etmem gerekmez - bir veya daha fazla açamazsam yine de devam edemem.

Bir dosya grubunda (en fazla 10 veya daha fazla) bir listeden bir döngü halinde açmanın bir yolu var mı?

1

6 cevap

Evet, bir liste anlama kullanabilirsiniz:

filenames = ['file1.txt', 'file2.txt', 'file3.txt'...]
filedata = {filename: open(filename, 'w') for filename in filenames}

Şimdi, açılan örneklerin tümü, dosya adına atanmış filedata klasörüne kaydedilir.

Onları kapatmak için:

for file in filedata.values():
    file.close()
6
katma
Bu yaklaşım ayrıca, bir yerde bir istisna veya erken çıkış varsa açık dosyaları kapattığınızdan emin olmak için her şeyin etrafında bir try/finally 'a ihtiyaç duyar.
katma yazar Kos, kaynak
Doğru fikrim vardı: bir sözlük, ancak dosya göstericisi nesnesinin filedata [dosyaadı] biçiminde olduğunu düşünmemiştim - bu gerçekten filepointer .
katma yazar ZZMike, kaynak

İyi haberler! Python 3.3 bunu yapmanın standart güvenli bir yolunu getiriyor .

from contextlib import ExitStack
with ExitStack() as stack:
    files = [stack.enter_context(open(fname)) for fname in filenames]
    # ... use files ...

Kod, ile ifadesini terk ettiğinde, önceden açılmış olan tüm dosyalar kapatılır.

Bu şekilde, eğer 2 dosya açılırsa ve üçüncü dosya açılmazsa, önceden açılmış olan iki dosyanın doğru şekilde kapatılacağını da bilirsiniz. Ayrıca, bloğu içinde içinde bir istisna ortaya çıkarsa, doğru temizliği görürsünüz.

4
katma

Çünkü çok fazla veri dosyası var. Dosya listesini manüel olarak bir listeye girmek yerine. Dosya isimlerini bununla bir listeye alabilirsiniz.

from os import listdir
from os.path import isfile, join
files_in_dir = [ f for f in listdir('/home/cam/Desktop') if isfile(join('/home/cam/Desktop',f)) ]

Şimdi yapabilirsin

for file in files_in_dir:
    with open(file, 'w') as f:
        f.do_something
3
katma

İstediğiniz kadar dosyayı açabilir ve daha sonra kapatmak için bir listede saklayabilirsiniz:

fds = [open(path, 'w') for path in paths]

# ... do stuff with files

# close files
for fd in fds:
    fd.close()

Veya daha iyi okunabilmesi için bir sözlük kullanabilirsiniz:

# map each file name to a file descriptor
files = {path: open(path, 'w') for path in paths}

# use file descriptors through the mapping
files['inventory'].write("Something")

# close files
for path in files:
    files[path].close()
2
katma

Açılan dosyaları garanti altına almak için anahtar kelimesini kullanın ( ve "bağlam yöneticileri" olarak bilinen diğer benzer kaynaklar kapalıdır:

with open(file_path, 'w') as output_file:
    output_file.write('whatever')

bloğundan çıktıktan sonra, bir istisna olsa bile dosya düzgün şekilde kapatılır.

İstediğiniz dosyalara giden bir yol listesi üzerinde kolayca geçiş yapabilirsiniz:

files = ['fp1.txt', 'inventory', 'orders']
for file in files:
    with open(file, 'w') as current_file:
        current_file.do_some_stuff()
2
katma

Yukarıdaki her iki cevap da, oluşturmak istediğiniz dosyaların listesini önceden biliyorsanız veya tanımlarsanız iyidir. Ancak, daha genel bir çözüm istemeniz durumunda, bu listeyi tam zamanında oluşturabilir, diskinizde boş dosyalar oluşturmak için işletim sisteminizi kullanabilirsiniz (bu, bulunduğunuz işletim sistemine bağlı olarak farklı şekillerde yapılır), ardından etkileşimli olarak dosyaların listesini oluşturur. bu yoldan:

import os
working_folder = input("Enter full path for the working folder/directory: ")
os.chdir(working_folder)
filenames_list = os.listdir()

#you can filter too, if you need so:
#filenames_list = [filename for filename in os.listdir() if '.txt' in filename]

#then you can do as Reut Sharabani and A.J. suggest above and make a list of file descriptors
file_descriptors = [open(filename, 'w') for filename in filenames_list]
#or a dictionary as Reut Sharabani suggests (I liked that one Reut :)

#do whatever you need to do with all those files already opened for writing

#then close the files
for fd in file_descriptors:
   fd.close()

"İle" kullanmak tamam; Bazılarının önerdiği gibi, aynı anda yalnızca bir dosyayla çalışıyorsanız (baştan sona kadar), ancak aynı anda tüm dosyalarla çalışmak istiyorsanız, dosya tanımlayıcılarının bir listesi veya sözlüğü daha iyidir.

1
katma