Forum >> Programmazione Python >> Scripting >> Esercizio...

Pagina: 1

Buongiorno,



mi sono avvicinato da poco a python e sto studiando su "Programmare con Python - Guida completa" scritto da Marco Buttu.

Ho appena finito il primo capito e stavo svolgendo il primo esercizio conclusivo; penso di aver compreso il tutto ma sto avendo un "problema" di cui non trovo la causa. L'esercizio riguarda la "lettura" di file ".data" contenenti righe di numeri; per ogni riga trovare il min(), max(), e medio e stamparli in un file di uscita su nuova directory rinominandoli ".dataout"; l'esercizio prevede che si utilizzi uno "spazio" per dividere le singole cifre in lettura, quindi .split(), io ho modificato un po' il codice per poter gestire anche .split(';') tramite un try/except...cosa succede...se creo 4 files ".data" due dei quali con separatore "spazio" e due con separatore ";" l'ultimo file trattato viene si creato ma vuoto (gli altri vengono riempiti correttamente)...ho inserito dei "counter" per verificare se i cicli vengono terminati corretamente ed è così; ho inserito dei print() per verificare lo stato dell'analisi/elaborazione del file e tutto sembra corretto.

Chiedo a chi ne sa di più un chiarimento di dove sto sbagliando...se può essere d'aiuto se cerco di cancellare il file ultimo creato ".dataout" non me lo lascia fare dicendomi che è aperto in python.

Sto usando la 3.6.0b4 su Windows10.

codice:

import sys
import os

out_dir_name = sys.argv1 if sys.argv[1:] else 'out'  # Nome directory output
try:
    os.mkdir(out_dir_name) # Crea la directory di output
    print('I file verranno scritti nella directory', out_dir_name)
except FileExistsError:
    print("I file verranno scritti nella directory", out_dir_name, "esistente")

for file_name in os.listdir():
    if file_name.endswith('.data'):
        out_file_name = os.path.join(out_dir_name, file_name + 'out')
        print('Sto per scrivere sul file `%s` ...' %out_file_name, end=' ')
        out = open(out_file_name, 'w')
        for line in open(file_name):
            try:
                d_t = [float(item) for item in line.split()] # Dati della linea
                out.write('%.2f   %.2f   %.2f\n' %(min(d_t), max(d_t), sum(d_t)/len(d_t)))
            except:
                d_e = [float(item) for item in line.split(';')] # Dati della linea
                out.write('%.2f   %.2f   %.2f\n' %(min(d_e), max(d_e), sum(d_e)/len(d_e)))
        print('Fatto!')
grazie
Ciao, il problema nasce dal flush del buffer. Quando scrivi su file, cio' che scrivi (tipicamente) non viene immediatamente scritto sul file-system. Viene tenuto in memoria, in un buffer. Il buffer viene svuotato automaticamente quando il file viene chiuso, oppure quando si chiama in modo esplicito il metodo flush() del file-object, o i metodi seek() e tell(). Guarda qua:




>>> f = open('myfile', 'w')

>>> f.write('pippo')

5





Se guardi il contenuto del file 'myfile', vedrai che e' ancora vuoto. Adesso chiudi il file:

>>> f.close()





Ora puoi verificare che il contenuto e' stato scritto su 'myfile'.

Nell'esempio che hai mostrato, il file non viene esplicitamente chiuso. Questo su Linux non crea (non dovrebbe creare...) problemi, perche' il file viene chiuso in modo automatico quando non vi sono piu' riferimenti ad esso. Su Windows evidentemente non e' cosi', e il file non viene chiuso, per cui il buffer non viene svuotato. Puoi risolvere il problema usando la parola chiave with (spiegata piu' avanti nel libro):

>>> with open('mynewfile', 'w') as f:

...     f.write('pippo')





Questa fa si che il file venga chiuso automaticamente all'uscita dal blocco with. Infatti puoi verificare che il contenuto e' stato scritto su 'mynewfile'. Altra cosa che puoi fare, piuttosto che usare with, e' mettere un out.close() nella linea sotto la print(), in modo da chiudere autometicamente il file.




Puoi anche gestire il buffering in modo diverso (spiegato cap.3). La open() ha infatti un parametro buffering, che ti consenti di personalizzare il buffering, per l'appunto. Ad esempio, se usi buffering=1, allora il contenuto del buffer verra' svuotato ad ogni newline:




>>> f = open('afile', 'w', buffering=1)

>>> f.write('ciaoooo\n')  # Nota che c'e' \n

8



Se fai una prova, vedrai che il testo e' stato gia' scritto sul file.




Detto cio', quello che mi pare strano e' che su Windows, al termine del processo, non venga chiuso il file e quindi svuotato il buffer. Qualcuno su Windows puo' verificare? Ad esempio, aprendo una sessione interattiva ed eseguendo:

>>> f = open('myfile', 'w')

>>> f.write('foooooo')

7

>>> import sys

>>> sys.exit(0)





Sul file 'myfile' e' presente il testo 'foooooo'?




PS. Nel prossimo capitolo viene descritto come utilizzare il modulo argparse della libreria standard, per gestire il parsing degli argomenti passati da linea di comando. Quello che hai visto in questo esercizio serve solamente per sapere cosa fa argparse dietro le quinte.
Marco Buttu
Ciao Marco,

gentile come sempre.
ho eseguito:

>>> f = open('myfile','w')
>>> f.write('fooooo')
6
>>> import sys
>>> sys.exit(0)

Il file viene creato ma vuoto...

se invece scrivo:

>>> with open('myfile','w') as f:
f.write('fooooo')


6
>>>
il file viene creato e "scritto"

Quindi in Windows il file non viene chiuso in automatico come in Linux-
grazie

Andrea



Pagina: 1



Esegui il login per scrivere una risposta.