Topic: Cosa succede in questo caso con imp.load_source?  (Letto 173 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline tommyb1992

  • python neanderthalensis
  • ****
  • Post: 299
  • Punti reputazione: 0
    • Mostra profilo
Cosa succede in questo caso con imp.load_source?
« il: Gennaio 14, 2019, 13:42 »

while 1:
  # cerca files .py in una cartella
  for fileName in allFilesFromFolder:
    # se il file non esiste lo carica dinamicamente in un dizionario
    if fileName not in loadedFiles:
      loadedFiles[name] = imp.load_source(name, fileName )


Ipotizzando di aggiungere un nuovo file .py alla cartella, potrebbe esiste il caso nel quale non essendo ancora stato tutto copiato/scaricato/trasferito load_source provi ad agire su un file incompleto e quindi terminarmi il programma con un raise?

Grazie

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 2.859
  • Punti reputazione: 9
    • Mostra profilo
Re:Cosa succede in questo caso con imp.load_source?
« Risposta #1 il: Gennaio 14, 2019, 19:30 »
Ma ti rendo conto che hai postato un pezzo di codice con esattamente SEI nomi non definiti? Di quante sfere di cristallo c'è bisogno per divinare quello che stai facendo davvero? Ora, nel caso specifico per fortuna (beh, diciamo...) questo non ha importanza importanza perché il tuo problema non sta comunque nel codice che hai postato, ma nella parte che non hai postato: e origina in ogni caso dal modo in cui questi nuovi file possono essere aggiunti alla directory, al di fuori del tuo codice. In ultima analisi questo dipende dalle primitive del sistema operativo che ci stanno dietro... Per esempio, se dietro c'è un "rename" Posix, allora dovrebbe essere atomico *se* le due path stanno nello stesso filesystem... e anche per Windows dovrebbe valere una cosa analoga... ma qui ci addentriamo in un dedalo di complicazioni mi sa (almeno per me che di file system ci capisco più o meno come di giardinaggio). In ogni caso, c'è ben poco python che c'entra qui.

Mi viene da dire (ma NON lo dico) che la cosa migliore è che tu faccia un po' di test (magari trasferendo file di qualche decina di giga, così da metterci un po' di tempo) e ti prepari a intercettare l'eccezione (OSError, se non riesci a stringere il campo).
Quello che invece dico è... ma che ti importa, poi? Il problema del tuo codice non nasce al momento di "caricare dinamicamente" nel dizionario, come dici... il problema nasce prima, al momento di determinare che cosa contiene "allFilesFromFolder" (che suppongo sia una lista... ah, avere la sfera di cristallo). Una volta che allFilesFromFolder è stato determinato, si chiude la saracinesca e il resto va da sé. A quel punto, o un file sta dentro allFilesFromFolder, oppure non ci sta. Da quel momento in poi, è ovvio che il contenuto reale della directory potrebbe cambiare. Ma solo una nuova operazione di scansione può dirtelo.
Al limite quindi bisognerebbe capire quale operazione fai per "riempire" allFilesFromFolder (ah, la sfera, la sfera di cristallo). Poniamo caso che sia il risultato di un os.listdir: allora (al limite) devi chiederti che cosa succede se qualcuno aggiunge un file nel bel mezzo di un os.listdir. E la risposta è, boh niente suppongo. Cioè, non credo che os.listdir sia di per sé "atomico" (specie su windows): nel senso, è possibile che tra il momento in cui inizia la scansione e il momento in cui finisce qualcosa cambi. Ma non so quanto possa importare: alla fine, os.listdir fa in tempo a vedere il nuovo file, oppure non fa in tempo. E se non fa in tempo, può non farcela per un decimillesimo di secondo o per una settimana ma l'unica è ripetere os.listdir una seconda volta. E più in generale, se proprio è quello che vuoi, metterti a fare polling della directory a intervalli regolari. In ogni caso, è naturale che, in generale, il contenuto "reale" della directory possa cambiare in seguito.

Offline tommyb1992

  • python neanderthalensis
  • ****
  • Post: 299
  • Punti reputazione: 0
    • Mostra profilo
Re:Cosa succede in questo caso con imp.load_source?
« Risposta #2 il: Gennaio 16, 2019, 13:51 »
Vabbe il codice l'ho scritto direttamente sull editor del forum, e poi diciamocelo, è piuttosto esplicativo, con quel:
# cerca files .py in una cartella
intendevo proprio che c'era un os.listdir che puttava tutto dentro a allFilesFromFolder.

Poi immaginavo che mettendomi a scaricare file pesanti e fare altri giochetti avrei potuto quanto meno "capire", però non ne avrei avuto la certezza...
p.s. stiamo parlando di un ambiente windows 7 o 10, e questo è solo per evitare di dover restartare il programma se faccio una modifica/aggiungo/tolgo files
« Ultima modifica: Gennaio 16, 2019, 13:55 da tommyb1992 »

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 2.859
  • Punti reputazione: 9
    • Mostra profilo
Re:Cosa succede in questo caso con imp.load_source?
« Risposta #3 il: Gennaio 16, 2019, 16:40 »
> è piuttosto esplicativo, con quel:
> # cerca files .py in una cartella

Sarà esplicativo per te che sai già che cosa c'è dietro. Ma chi ti legge, come fa a sapere QUALE operazione in concreto stai usando per "cercare files in una cartella"?

> e questo è solo per evitare di dover restartare il programma se faccio una modifica/aggiungo/tolgo files

eh, ma questo invece è proprio quello che dovrai fare in ogni caso, invece... Nel senso: anche lasciando perdere casi estremi (race conditions... boh, non so), resta che quando fai os.listdir su una directory ottieni uno "snapshot" della situazione *in quel momento*. Nell'intervallo che corre tra quel momento e il momento in cui operi effettivamente sui file (per esempio li apri), non hai nessuna garanzia che la situazione non sia già cambiata. In particolare, visto che lo hai menzionato (e io me n'ero dimenticato), il problema più grave non ce l'hai quando viene *aggiunto* un file ma quando ti viene *tolto* da sotto il naso. Anche solo se fai quacosa come

for item in os.listdir('.'):
    with open(item, 'r') as f:
        f.read()

può darti errore: se ci sono molti molti file e sono molto pesanti, se sei abbastanza svelto riesci addirittura a crashare il programma togliendo "a mano" uno degli ultimi file della directory prima che python arrivi a leggerlo...
Tutto questo per dirti, ripeto, che il tuo problema
a) non è tanto preoccuparti di "coincidenze" strane nel momento in cui "riempi la lista con i nomi dei file". Per quello puoi fidarti abbastanza delle primitive del sistema operativo sottostante
b) non è tanto preoccuparti che dopo che hai "riempito la lista" qualcosa possa cambiare nella directory: questo è normale e *sicuramente* potrebbe accadere. Devi rassegnarti a questa possibilità. Al limite puoi fare polling della directory a tempi regolari, se proprio per te è importante.
c) invece devi preoccuparti di "coincidenze" strane nel momento in cui *apri* ciascun file per lavorarci. E' in quel momento che devi essere pronto a intercettare l'eccezione appropriata (il file non esiste più, oppure è aperto in scrittura da un altro processo, etc.).

Offline tommyb1992

  • python neanderthalensis
  • ****
  • Post: 299
  • Punti reputazione: 0
    • Mostra profilo
Re:Cosa succede in questo caso con imp.load_source?
« Risposta #4 il: Gennaio 18, 2019, 06:23 »
Ok dai ti ringrazio per le parole spese, sei sempre piuttosto esaustivo, ma l'ultima condizione da te citata mi fa desidere da ogni "genialità", mi rassegno e re-starto tutto.