Topic: [Risolto] Aggiornamento output nel terminale con end=''  (Letto 28 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline nuzzopippo

  • python habilis
  • **
  • Post: 67
  • Punti reputazione: 0
    • Mostra profilo
Signori, i miei saluti.

In fase di test di una classe in sviluppo per un oggetto dedicato alla scansione di lan locale per l'individuazione di eventuali hosts  in ascolto ho riscontrato un curioso "effetto" utilizzando una istruzione
print('.', end='')

con output destinato ad un normale trminale bash : l'output relativo NON viene mostrato prima della conclusione del processo (un po' lunghetto).

Il problema si presenta anche in caso si utilizzi uno spazio quale terminazione del print mentre funziona regolarmente in caso di utilizzo di un newline.

... Curioso ma non stranissimo il fenomeno, mi sta facendo "incarognare" ma per quanto ci giri attorno e cerchi in rete non sto trovando soluzione (un time.sleep(qualcosa) non serve), non riesco a far aggiornare quel dannato output.
È probabile la "soluzione" sia banale ma proprio non mi riesce di immaginare dove altro cercarla ... qualcuno conosce la problematica?

Non credo se serva in merito, ma giusto in caso io ne sia inconsapevole causa, questo è l'oggetto che dovrebbe produrre quell'output (con tutte le "sporcature" del litigio

class ScanPortLan():
    '''
Esegue la scansione di una specifica porta su tutti gli indirizzi della rete
locale al fine di individuare su quali macchine vi è "qualcosa" in ascolto.
    '''
    def __init__(self, ip, porta):
        '''
Inizializzazione dell'oggetto, memorizza quali variabili di istanza l'indirizzo
locale e la porta da verificare.

Parametri : ip    - stringa dell'indirizzo ipv4 della macchina
            porta - porta da verificare
        '''
        self.ind_ascolto = []
        self.my_ip = ip
        self.porta = porta
        self.scan()
   
    def scan(self):
        '''
Tenta una connessione alla porta definita nel range 1/254 della rete locale,
escluso il proprio indirizzo.
Memorizza gli indirizzi che hanno dato risposta.
        '''
        base = self.my_ip.split('.')
        base_ind = '.'.join(base[:-1])
        for p in range(1, 255):
            curr_ip = base_ind + '.' + str(p)
            if curr_ip != self.my_ip:
                if self.connetti(curr_ip):
                    print('\n', curr_ip, '<-->', 'CONNESSO')
                    self.ind_ascolto.append(curr_ip)
                else:
                #print('.', end='')
                    #print('.', end=' ')
                    print('.', end='\n')
                    #print('.')
            time.sleep(0.5)
        print()
        print('Hosts in ascolto:')
        for ip in self.ind_ascolto:
            print('\t', ip)
   
    def connetti(self, ip):
        try:
            s = socket.socket(socket.AF_INET)
            s.settimeout(0.5)
            s.connect((ip, self.porta))
            result = True
        except OSError:
            result = False
        finally:
            if s:
                s.close()
        return result

Manca la restituzione di quanto trovato.

questa è la sua corrente invocazione di test

if __name__ == '__main__':
    llhr = LocalLanHdwRec()
    for ip in llhr.get_ip4():
        ScanPortLan(ip, 21)


e questo è un esempio della disdicevole casistica :

NzP:~$ python3 recognizer.py
^C..............Traceback (most recent call last):
  File "recognizer.py", line 106, in <module>
    ScanPortLan(ip, 21)
  File "recognizer.py", line 64, in __init__
    self.scan()
  File "recognizer.py", line 82, in scan
    time.sleep(0.5)
KeyboardInterrupt
NzP:~$ python3 recognizer.py


Ciao e grazie dell'attenzione :)
« Ultima modifica: Ottobre 06, 2019, 06:29 da nuzzopippo »

Offline nuzzopippo

  • python habilis
  • **
  • Post: 67
  • Punti reputazione: 0
    • Mostra profilo
Re:Aggiornamento output nel terminale con end=''
« Risposta #1 il: Ottobre 06, 2019, 06:28 »
Della serie non bisogna mai intestardirsi ...

Riletta stamattina la docs
>>> help('print')
Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
...   


Mi è subito saltato agli occhi quel "flush=False" ... posto a "True", ovviamente funziona come "mi aspettavo" ... e si che l'avevo riletto 50 volte :(

Chiedo scusa per il post così "scemo" ... ero entrato in loop

Offline GlennHK

  • python sapiens sapiens
  • ******
  • Post: 1.654
  • Punti reputazione: 1
    • Mostra profilo
    • La Tana di GlennHK
Re:[Risolto] Aggiornamento output nel terminale con end=''
« Risposta #2 il: Ottobre 06, 2019, 11:41 »
Sì, è dovuto al fatto che l'output di default di print (sys.stdout) viene flushato solo ad ogni fine linea.