Estou escrevendo um downloader FTP. Parte do código é algo assim:
ftp.retrbinary("RETR " + file_name, process)
Estou chamando o processo de função para lidar com o retorno de chamada:
def process(data):
print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
file.write(data)
e a saída é algo assim:
1784 KB / KB 1829 downloaded!
1788 KB / KB 1829 downloaded!
etc...
mas eu quero imprimir esta linha e da próxima vez reimprimir / atualizar para que ela mostre apenas uma vez e eu verei o progresso desse download.
Como pode ser feito?
python
refresh
progress-bar
Kristian
fonte
fonte
Respostas:
Este é o código para Python 3.x:
A
end=
palavra-chave é o que faz o trabalho aqui - por padrão,print()
termina em um\n
caractere de nova linha ( ), mas pode ser substituído por uma string diferente. Nesse caso, terminar a linha com um retorno de carro, em vez disso, retorna o cursor para o início da linha atual. Portanto, não há necessidade de importar osys
módulo para esse tipo de uso simples.print()
na verdade, tem vários argumentos de palavra-chave que podem ser usados para simplificar bastante o código.Para usar o mesmo código no Python 2.6+, coloque a seguinte linha na parte superior do arquivo:
fonte
from __future__ import print_function
.print "foo",
No entanto, você ainda precisa limpar depois disso para ver a mudança:sys.stdout.flush()
\r
no início da string e definir, emend=''
vez disso, para fazer isso funcionar. Eu não acho que meu terminal goste quando eu terminar com\r
flush=True
àprint()
função para garantir que o buffer seja liberado (o buffer de linha padrão só seria liberado quando uma\n
nova linha fosse escrita).\r
no início eend=''
funcionou melhor e mais suave. Usarflush=True
com\r
no final se a string eend='\r'
também funcionou, mas não foi suave e apagou a linha e seu avanço de linha.Se tudo o que você deseja fazer é alterar uma única linha, use
\r
.\r
significa retorno de carro. Seu efeito é apenas colocar o cursor de volta no início da linha atual. Não apaga nada. Da mesma forma,\b
pode ser usado para retroceder um caractere. (alguns terminais podem não suportar todos esses recursos)fonte
\r
significa retorno de carro. seu efeito é apenas colocar o cursor de volta no início da linha atual. não apaga nada. da mesma forma,\b
pode ser usado para retroceder um caractere. (alguns terminais podem não oferecer suporte a todos esses recursos)sys.stdout.write('%s\r', size_str')
eu acho que você quis dizer,sys.stdout.write('%s\r' % size_str)
mas não funciona.print
vez desys.stdout.write
se preferir:print size_str + "\r",
funciona bem. O,
no final da instrução print suprime a nova linha;sys.stdout.flush()
ainda é necessárioDê uma olhada na documentação do módulo curses e no HOWTO do módulo curses .
Exemplo realmente básico:
fonte
clrtoeol
para quando a segunda linha for mais curta que a primeira.Aqui está minha pequena classe que pode reimprimir blocos de texto. Ele limpa corretamente o texto anterior para que você possa substituir o texto antigo por um novo texto mais curto, sem criar confusão.
fonte
Descobri que, para uma instrução de impressão simples no python 2.7, basta colocar uma vírgula no final após o seu
'\r'
.Isso é mais curto do que outras soluções não-python 3, mas também mais difícil de manter.
fonte
Você pode simplesmente adicionar '\ r' no final da string mais uma vírgula no final da função de impressão. Por exemplo:
fonte
end
parâmetro padrão definido para\n
so u print(...)KB downloaded!\r\n
. Estou errado?end = '\r'
vez disso, o uso corrige o problema no Python 3.Estou usando o spyder 3.3.1 - windows 7 - python 3.6, embora o flush possa não ser necessário. com base nesta postagem - https://github.com/spyder-ide/spyder/issues/3437
fonte
para substituir a linha anterior em python, tudo o que você precisa é adicionar end = '\ r' à função de impressão, teste este exemplo:
fonte