nhiều bản in trên cùng một dòng trong Python


229

Tôi muốn chạy một kịch bản, về cơ bản hiển thị một đầu ra như thế này:

Installing XXX...               [DONE]

Hiện tại, tôi in Installing XXX...trước rồi mới in [DONE].

Tuy nhiên, bây giờ tôi muốn in Installing xxx...[DONE]trên cùng một dòng.

Có ý kiến ​​gì không?



1
Các câu trả lời cho câu hỏi này không đề cập đến việc đôi khi bạn muốn xóa dòng, xem: stackoverflow.com/questions/45263205
ideaman42

Câu trả lời:


284

Bạn có thể sử dụng printcâu lệnh để làm điều này mà không cần nhập sys.

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

install_xxx()
print "[DONE]"

Dấu phẩy ở cuối printdòng ngăn không cho printphát hành một dòng mới (bạn nên lưu ý rằng sẽ có thêm một khoảng trắng ở cuối đầu ra).

Giải pháp Python 3
Vì ở trên không hoạt động trong Python 3, bạn có thể thực hiện việc này thay vào đó (một lần nữa, mà không cần nhập sys):

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

install_xxx()
print("[DONE]")

Hàm in chấp nhận một end tham số mặc định "\n". Đặt nó thành một chuỗi trống sẽ ngăn nó phát ra một dòng mới ở cuối dòng.


1
Nó hoạt động hoàn hảo. Cho đến nay chỉ thấy các giải pháp xuất sắc. Thực sự tốt để biết rằng.
Prometheus

5
Điều này không hoạt động nếu bạn có cả hai bản in và một hành động tốn thời gian ở giữa (tất cả trong cùng một chức năng / mức độ thụt lề). Trước khi hành động bắt đầu, không có đầu ra nào cả và sau khi kết thúc, đầu ra xuất hiện dưới dạng toàn bộ
Paddre

2
Đó có lẽ là một chức năng của bộ đệm đầu ra được HĐH tạo ra cho toàn bộ quá trình, đây không phải là vấn đề cụ thể của python. Xem stackoverflow.com/questions/107705 để biết cách giải quyết dành riêng cho python.
nhiều giao diện

13
Nếu không có dòng mới, có lẽ bạn muốn xóa bộ đệm một cách rõ ràng. Sử dụngprint("...", end="", flush=True) trong Python 3, trong Python 2 thêm một sys.stdout.flush()cuộc gọi.
Martijn Pieters

7
trong python 3.x bạn sẽ muốn thêm "\ r" vào cuối để thay thế dòng in VS nối thêm vào cuối của nóprint("Progress: {}%".format(var), end="\r", flush=True)
John

103

Bạn chỉ có thể sử dụng này:

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

và đầu ra sẽ là

something else

Không cần phải overkill bằng import sys. Hãy chú ý đến biểu tượng dấu phẩy ở cuối.

Python 3+ print("some string", end=""); để loại bỏ chèn dòng mới ở cuối. Đọc thêm bởihelp(print);


3
Lưu ý có hai khoảng trắng bằng cách sử dụng phương pháp này
ethanjyx

1
Đây là câu trả lời đơn giản và hiệu quả nhất.
gixxer

Điều này không hoạt động khi các đối số của in nằm trong ngoặc đơn. Công việc này: <in "xin chào",; print ("hello")> nhưng điều này không hoạt động <print ("hello",); in ("xin chào")>
Mayank Jaiswal

@MayankJaiswal Điều này không hoạt động với parens. in ('xin chào'),
drglove

1
printHàm có cú pháp hơi khác nhau trong python 2 VS 3.
boldnik

52

Bạn nên sử dụng backspace ' \ r ' hoặc (' \ x08 ') để quay lại vị trí trước đó trong đầu ra của bàn điều khiển

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

Con trăn 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

Mã này sẽ được tính từ 0% đến 100% trên một dòng. Giá trị cuối cùng sẽ là:

> python test.py
100%

Thông tin bổ sung về tuôn ra trong trường hợp này tại đây: Tại sao các câu lệnh in python có chứa các đối số 'end =' hoạt động khác nhau trong các vòng lặp while?


1
Để làm rõ, có vẻ như mã nhận xét trong ví dụ này là dành cho Python 2 và các dòng không nhận xét dành cho Python 3.
Turtles Are Cute

1
các dòng bouth sẽ hoạt động tốt trong Python 3. Nếu bạn sử dụng '\ x08' làm khoảng lùi, bạn cần xóa luồng đầu ra - print ((b '\ x08' * n) .decode (), end = '', flush = Đúng)
Vadim Zin4uk 10/03/2015

1
Việc trả lại xe ngựa '\ r' quay trở lại từ đầu của dòng, vì vậy '* n' là không cần thiết
bjnortier

43

Sử dụng sys.stdout.write('Installing XXX... ')sys.stdout.write('Done'). Theo cách này, bạn phải thêm dòng mới bằng tay "\n"nếu bạn muốn tạo lại chức năng in. Tôi nghĩ rằng có thể không cần thiết phải sử dụng những lời nguyền chỉ cho việc này.


4
Cá nhân tôi thích giải pháp này cho giải thưởng được bình chọn cao hơn vì nó hoạt động chính xác theo cách tương tự trên python2.x và python3.x mà không cần phải dựa vào __future__nhập khẩu hoặc bất cứ điều gì tương tự.
mgilson

17

Không có câu trả lời nào phù hợp với tôi vì tất cả đều tạm dừng cho đến khi gặp một dòng mới. Tôi đã viết một người trợ giúp đơn giản:

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

Để kiểm tra nó:

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

"xin chào" trước tiên sẽ in ra và xả vào màn hình trước khi ngủ. Sau đó, bạn có thể sử dụng in tiêu chuẩn.


1
Cảm ơn bạn! Chính xác những gì tôi cần aka .flush ()
MrNice


11

Đơn giản nhất:

Con trăn 3

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

Nó có nghĩa là nó sẽ quay lại con trỏ để bắt đầu, hơn là sẽ in một cái gì đó và sẽ kết thúc trong cùng một dòng. Nếu trong một vòng lặp, nó sẽ bắt đầu in ở cùng một nơi nó bắt đầu.


3
Mát mẻ! Hoạt động trong Windows là tốt.
Shital Shah

2
Cảm ơn điều này hoạt động tốt cho tôi! Tôi nghĩ rằng đó print(’something to be override’, end=‘\r’)là đơn giản hơn, mặc dù.
Tropilio

9

Ví dụ đơn giản này sẽ in 1-10 trên cùng một dòng.

for i in range(1,11):
    print (i, end=" ")

9

In có một endđối số tùy chọn , đó là những gì được in cuối cùng. Mặc định là một dòng mới, nhưng bạn có thể thay đổi nó thành chuỗi trống. ví dụprint("hello world!", end="")


2
Đây là trong python 3. Trong python 2 bạn có thể đơn giản print 'something',. Dấu phẩy ở cuối ngăn chặn việc thêm một dòng mới.
arjoonn

4

Nếu bạn muốn ghi đè lên dòng trước đó (thay vì liên tục thêm vào dòng đó), bạn có thể kết hợp \rvới print(),ở cuối câu lệnh in. Ví dụ,

from time import sleep

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

print("...DONE!")

sẽ đếm từ 0 đến 9, thay thế số cũ trong bảng điều khiển. Các"...DONE!" sẽ in trên cùng một dòng như quầy ngoái, 9.

Trong trường hợp của bạn cho OP, điều này sẽ cho phép bảng điều khiển hiển thị phần trăm hoàn tất cài đặt dưới dạng "thanh tiến trình", trong đó bạn có thể xác định vị trí ký tự bắt đầu và kết thúc và cập nhật các điểm đánh dấu ở giữa.

print("Installing |XXXXXX              | 30%"),

4

Đây là phiên bản tương thích 2.7 có nguồn gốc từ phiên bản 3.0 của @ Vadim-Zin4uk:

Con trăn 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)

Đối với vấn đề đó, giải pháp 3.0 được cung cấp có vẻ hơi cồng kềnh. Ví dụ, phương thức backspace không sử dụng đối số nguyên và có thể được loại bỏ hoàn toàn.

Con trăn 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

Cả hai đã được thử nghiệm và làm việc.


2

Đây là một chủ đề rất cũ, nhưng đây là một câu trả lời rất kỹ lưỡng và mã mẫu.

\rlà biểu diễn chuỗi của Vận chuyển trở lại từ bộ ký tự ASCII. Nó giống như bát phân 015[ chr(0o15)] hoặc hexidecimal 0d[ chr(0x0d)] hoặc thập phân 13[ chr(13)]. Xem man asciicho một đọc nhàm chán. Nó ( \r) là một đại diện di động khá dễ dàng và đủ để mọi người đọc. Nó rất đơn giản có nghĩa là di chuyển cỗ xe trên máy đánh chữ suốt từ đầu trở lại mà không cần tiến bộ giấy. Đó là CRmột phần trong CRLFđó có nghĩa là Vận chuyển trở lại và Nguồn cấp dữ liệu .

print()là một hàm trong Python 3. Trong Python 2 (bất kỳ phiên bản nào bạn muốn sử dụng), printcó thể được buộc vào một hàm bằng cách nhập định nghĩa của nó từ __future__mô-đun. Lợi ích của printchức năng là bạn có thể chỉ định những gì sẽ in ở cuối, ghi đè hành vi mặc định của \nviệc in một dòng mới vào cuối mỗi print()cuộc gọi.

sys.stdout.flushyêu cầu Python tuôn ra đầu ra của đầu ra tiêu chuẩn , đó là nơi bạn gửi đầu ra print()trừ khi bạn chỉ định khác. Bạn cũng có thể có hành vi tương tự bằng cách chạy với python -uhoặc cài đặt biến môi trường PYTHONUNBUFFERED=1, do đó bỏ qua import syssys.stdout.flush()gọi. Số tiền bạn có được bằng cách thực hiện gần như bằng 0 và không dễ gỡ lỗi nếu bạn quên một cách thuận tiện rằng bạn phải thực hiện bước đó trước khi ứng dụng của bạn hoạt động đúng.

Và một mẫu. Lưu ý rằng điều này chạy hoàn hảo trong Python 2 hoặc 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()

Tôi nghĩ rằng câu trả lời của bạn phù hợp hơn cho: stackoverflow.com/questions/45263205/ấc
Marc Cayuela Rafols

2

print () có một tham số "end" được xây dựng theo mặc định được đặt thành "\ n" Calling print ("This is America") thực sự đang gọi print ("Đây là America", end = "\ n"). Một cách dễ dàng để làm là gọi in ("Đây là nước Mỹ", end = "")


1

Chỉ trong trường hợp bạn đã lưu trữ trước các giá trị trong một mảng, bạn có thể gọi chúng theo định dạng sau:

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

1

Python nối thêm dòng mới vào cuối để in. Sử dụng end = '' cho python3 cho phương thức in để nối thêm khoảng trắng thay vì dòng mới. đối với python2 sử dụng dấu phẩy ở cuối câu lệnh in.

print("Foo",end=' ')
print('Bar')

0

Tìm thấy bài Quora này , với ví dụ này hoạt động với tôi (python 3), gần với những gì tôi cần nó (nghĩa là xóa toàn bộ dòng trước đó).

Ví dụ họ cung cấp:

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

Để in trên cùng một dòng, như những người khác đã đề xuất, chỉ cần sử dụng end=""


-2

Tôi đã tìm thấy giải pháp này và nó đang hoạt động trên 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

1
Đó printlà cú pháp không chính xác cho Python 2.7 và mã không hoạt động ngay cả với cú pháp đúng.
Cory Madden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.