várias impressões na mesma linha em Python

229

Eu quero executar um script, que basicamente mostra uma saída como esta:

Installing XXX...               [DONE]

Atualmente, imprimo Installing XXX...primeiro e depois imprimo [DONE].

No entanto, agora eu quero imprimir Installing xxx...e [DONE]na mesma linha.

Alguma ideia?

user697108
fonte
1
Respostas a esta pergunta não mencionar que às vezes você quer limpar a linha, consulte: stackoverflow.com/questions/45263205
ideasman42

Respostas:

284

Você pode usar a printinstrução para fazer isso sem importar sys.

def install_xxx():
   print "Installing XXX...      ",

install_xxx()
print "[DONE]"

A vírgula no final da printlinha impedeprint emissão de uma nova linha (observe que haverá um espaço extra no final da saída).

A solução Python 3
Como as opções acima não funcionam no Python 3, você pode fazer isso (novamente, sem importar sys):

def install_xxx():
    print("Installing XXX...      ", end="", flush=True)

install_xxx()
print("[DONE]")

A função de impressão aceita um endparâmetro com o padrão "\n". A configuração para uma sequência vazia impede que uma nova linha seja emitida no final da linha.

multipleinterfaces
fonte
1
Funciona perfeitamente. Só tinha visto soluções stdout até agora. Muito bom saber disso.
Prometheus
5
Isso não funciona se você tiver impressões e uma ação demorada (todas na mesma função / nível de indentação). Antes do início da ação, não há nenhuma saída em tudo e depois de concluído a saída aparece como um todo
Paddre
2
Isso provavelmente é mais uma função do buffer de saída pré-formado pelo sistema operacional para o processo como um todo, o que não é um problema específico do python. Consulte stackoverflow.com/questions/107705 para obter uma solução alternativa específica para python.
multipleinterfaces
13
Sem uma nova linha, você provavelmente deseja liberar explicitamente o buffer. Use print("...", end="", flush=True)no Python 3, no Python 2 adicione uma sys.stdout.flush()chamada.
Martijn Pieters
7
em 3.x python você vai querer adicionar um "\ r" para acabar com a substituir a linha impressa VS anexando ao final do mesmoprint("Progress: {}%".format(var), end="\r", flush=True)
John
103

Você pode simplesmente usar isso:

print 'something',
...
print ' else',

e a saída será

something else

não há necessidade de exagerar import sys . Preste atenção ao símbolo de vírgula no final.

Python 3+ print("some string", end=""); para remover a inserção de nova linha no final. Leia mais porhelp(print);

boldnik
fonte
3
Observe que há dois espaços, utilizando este método
ethanjyx
1
Essa é a resposta mais simples e mais eficiente.
Gixxer #
Isso não funciona quando os argumentos de impressão estão entre parênteses. Isso funciona: <print "hello"; print ("olá")> mas isso não funciona <print ("olá",); print ("olá")>
Mayank Jaiswal
@MayankJaiswal Isso funciona com os parênteses. print ('olá'),
drglove 6/02/16
1
printfunção tem uma sintaxe ligeiramente diferente em python 2 VS 3.
boldnik
52

Você deve usar o backspace ' \ r ' ou (' \ x08 ') char para voltar à posição anterior na saída do console

Python 2+:

import time
import sys

def backspace(n):
    sys.stdout.write((b'\x08' * n).decode()) # use \x08 char to go back   

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    sys.stdout.write(s)                     # just print
    sys.stdout.flush()                      # needed for flush when using \x08
    backspace(len(s))                       # back n chars    
    time.sleep(0.2)                         # sleep for 200ms

Python 3:

import time   

def backline():        
    print('\r', end='')                     # use '\r' to go back


for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print(s, end='')                        # just print and flush
    backline()                              # back to the beginning of line    
    time.sleep(0.2)                         # sleep for 200ms

Este código contará de 0% a 100% em uma linha. O valor final será:

> python test.py
100%

Informações adicionais sobre liberação neste caso aqui: Por que as instruções de impressão python que contêm argumentos 'end =' se comportam de maneira diferente nos loops while?

Vadim Zin4uk
fonte
1
Para esclarecer, parece que o código comentado-out neste exemplo é para Python 2, e as linhas não comentou são para Python 3.
As tartarugas são bonitos
1
as linhas bouth funcionarão bem no Python 3. Se você usar '\ x08' como backspace, precisará liberar o fluxo de saída - print ((b '\ x08' * n) .decode (), end = '', flush = Verdadeiro)
Vadim Zin4uk
1
O retorno de carro '\ r' vai voltar para o início da linha, de modo que o '* n' é desnecessária
bjnortier
43

Use sys.stdout.write('Installing XXX... ')e sys.stdout.write('Done'). Dessa forma, você precisará adicionar a nova linha manualmente, "\n"se desejar recriar a funcionalidade de impressão. Eu acho que pode ser desnecessário usar maldições apenas para isso.

ferostar
fonte
4
Pessoalmente, prefiro essa solução à que foi votada com mais votos, porque funciona exatamente da mesma maneira em python2.xe python3.x sem precisar depender de __future__importações ou algo do tipo.
mgilson
17

Nenhuma das respostas funcionou para mim, pois todas elas pararam até que uma nova linha foi encontrada. Eu escrevi um ajudante simples:

def print_no_newline(string):
    import sys
    sys.stdout.write(string)
    sys.stdout.flush()

Para testá-lo:

import time
print_no_newline('hello ')
# Simulate a long task
time.sleep(2)
print('world')

"olá" será impresso primeiro e nivelado na tela antes do sono. Depois disso, você pode usar a impressão padrão.

hyprnick
fonte
1
Obrigado! Exatamente o que eu precisava aka .flush ()
MrNice
11

Mais simples:

Python 3

    print('\r' + 'something to be override', end='')

Isso significa que o cursor voltará ao início, imprimirá algo e terminará na mesma linha. Se em um loop, ele começará a imprimir no mesmo local em que inicia.

Sunfloro
fonte
3
Legal! Funciona no Windows também.
Shital Shah 13/02/19
2
Graças isso funciona bem para mim! Eu acho que print(’something to be override’, end=‘\r’)é mais simples, no entanto.
Tropilio 10/04/19
9

Este exemplo simples imprimirá de 1 a 10 na mesma linha.

for i in range(1,11):
    print (i, end=" ")
Umali Leonard
fonte
9

A impressão tem um endargumento opcional , é o que foi impresso no final. O padrão é uma nova linha, mas você pode alterá-la para uma string vazia. por exemploprint("hello world!", end="")

TulkinRB
fonte
2
Isso está no python 3. No python 2, você pode simplesmente print 'something',. A vírgula no final impede a adição de uma nova linha.
Arjoonn 6/09/15
4

Se você deseja sobrescrever a linha anterior (em vez de adicioná-la continuamente), você pode combinar \rcom print(),no final da declaração de impressão. Por exemplo,

from time import sleep

for i in xrange(0, 10):
    print("\r{0}".format(i)),
    sleep(.5)

print("...DONE!")

contará de 0 a 9, substituindo o número antigo no console. o"...DONE!" imprimirá na mesma linha que o último contador, 9.

No seu caso para o OP, isso permitiria que o console exibisse uma porcentagem concluída da instalação como uma "barra de progresso", onde você pode definir uma posição inicial e final dos caracteres e atualizar os marcadores no meio.

print("Installing |XXXXXX              | 30%"),
Brian Bunker
fonte
4

Aqui está uma versão compatível com 2.7 derivada da versão 3.0 por @ Vadim-Zin4uk:

Python 2

import time

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print '{0}\r'.format(s),                # just print and flush

    time.sleep(0.2)

Por esse motivo, a solução 3.0 fornecida parece um pouco inchada. Por exemplo, o método backspace não utiliza o argumento inteiro e provavelmente poderia ser eliminado por completo.

Python 3

import time

for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    print('{0}\r'.format(s), end='')        # just print and flush

    time.sleep(0.2)                         # sleep for 200ms

Ambos foram testados e funcionam.

Dannid
fonte
2

Este é um tópico muito antigo, mas aqui está uma resposta muito detalhada e um código de exemplo.

\ré a representação de sequência de retorno de carro do conjunto de caracteres ASCII. É o mesmo que octal 015[ chr(0o15)] ou hexidecimal 0d[ chr(0x0d)] ou decimal 13[ chr(13)]. Veja man asciipara uma leitura chata. É ( \r) uma representação bastante portátil e é fácil o suficiente para as pessoas lerem. Simplesmente significa mover o carro na máquina de escrever de volta ao início sem avançar o papel. É a CRparte CRLFque significa retorno de carro e avanço de linha .

print()é uma função no Python 3. No Python 2 (qualquer versão que você esteja interessado em usar), printpode ser forçado a entrar em uma função importando sua definição do __future__módulo. O benefício da printfunção é que você pode especificar o que imprimir no final, substituindo o comportamento padrão de \nimprimir uma nova linha no final de cada print()chamada.

sys.stdout.flushdiz ao Python para liberar a saída da saída padrão , que é onde você envia a saída, a print()menos que você especifique o contrário. Você também pode obter o mesmo comportamento executando python -uou definindo a variável de ambiente PYTHONUNBUFFERED=1, ignorando as chamadas import syse sys.stdout.flush(). A quantia que você ganha fazendo isso é quase exatamente zero e não é muito fácil de depurar se você esquecer convenientemente que precisa fazer essa etapa antes que seu aplicativo se comporte corretamente.

E uma amostra. Observe que isso funciona perfeitamente no Python 2 ou 3.

from __future__ import print_function

import sys
import time

ANS = 42
FACTORS = {n for n in range(1, ANS + 1) if ANS % n == 0}

for i in range(1, ANS + 1):
    if i in FACTORS:
        print('\r{0:d}'.format(i), end='')
        sys.stdout.flush()
        time.sleep(ANS / 100.0)
else:
    print()
Chris Cosby
fonte
Eu acho que a resposta é mais adequado para: stackoverflow.com/questions/45263205/...
Marc Cayuela Rafols
2

print () possui um parâmetro interno "end" definido por padrão como "\ n" Chamar print ("This is America") está chamando print ("This is America", end = "\ n"). Uma maneira fácil de fazer é ligar para print ("This is America", end = "")

Miles Mbo
fonte
1

Caso você tenha pré-armazenado os valores em uma matriz, você pode chamá-los no seguinte formato:

for i in range(0,n):
       print arr[i],
k20392
fonte
1

Python acrescenta nova linha como um fim para imprimir. Use end = '' para python3 para o método print para acrescentar um espaço em vez de uma nova linha. para python2 use vírgula no final da declaração de impressão.

print("Foo",end=' ')
print('Bar')
MrKulli
fonte
0

Encontrei este post do Quora , com este exemplo que funcionou para mim (python 3), mais próximo do que eu precisava (ou seja, apagando toda a linha anterior).

O exemplo que eles fornecem:

def clock():
   while True:
       print(datetime.now().strftime("%H:%M:%S"), end="\r")

Para imprimir na mesma linha, como outros sugeriram, basta usar end=""

Mircea
fonte
-2

Encontrei esta solução e está funcionando no Python 2.7

# Working on Python 2.7 Linux

import time
import sys


def backspace(n):
    print('\r', end='')                     # use '\r' to go back


for i in range(101):                        # for 0 to 100
    s = str(i) + '%'                        # string for output
    sys.stdout.write(string)
    backspace(len(s))                       # back for n chars
    sys.stdout.flush()
    time.sleep(0.2)                         # sleep for 200ms
Luis Silva
fonte
1
Essa printé uma sintaxe incorreta para o Python 2.7 e o código não funciona mesmo com a sintaxe correta.
Cory Madden #