簡體   English   中英

在等待 python 中的輸入時打印到控制台

[英]Print to console while waiting for input in python

我有一個 python 腳本(用作命令行界面),它使用input function 等待輸入查詢。

while True:
  query = input('Enter query: ')
  thread = Thread(target=exec_query, args=(query,))
  thread.start()

同時,一個工作線程正在執行這樣的查詢。 使用print function 將查詢的 output 打印到命令行。

def exec_query(query_data):
  # doing a complex data processing ...
  print('results of the query')

因此,打印 function 的 output 寫在第二次執行打印 function 打印的前綴'Enter query: '后面:

Enter query: {the query}
Enter query: results of the query

我想實現在前綴'Enter query: '之前插入打印 function 的 output (或者看起來像這樣):

Enter query: {the query}
results of the query
Enter query:

我已經通過了一些方法,但沒有找到一個好的解決方案。 一種解決方法是通過添加'\x1b[1A\x1b[2K'刪除前綴,並在打印查詢執行的 output 后將其寫回。 這里的問題是,我不知道如何重建用戶此時可能已經插入的不完整的用戶輸入(查詢)。

使用這個從終端讀取 1 個字符

  • 返回字節
    • 通過bytes.decode()獲取str
  • 不回顯(打字不可見)
    • 而不是msvcrt.getch_GetchWindows.__call__中使用.getche
  • msvcrt不是全局導入的

做類似的事情

while input != '\r': # or some other return char, depends
    input += getch().decode()

# in front of erase
while msvcrt.kbhit(): # read while there is something to read
    remember_input += getch().decode()
print(erase)
# and than you should return remember_input to stdin somehow (try msvcrt.putch)

由於復雜性(使用線程編寫(我是新手)、輸入/輸出控制(因為我的 vsc 終端每次都討厭我),以及可能更多的原因,我太累了考慮到),
但我相信你不會放棄

編輯:哦,是的
我忘了提到您可能還想編寫自己的printinput
在這種情況下有用的東西將是input(prompt, remember_string)
提示將無法被退格鍵刪除,並且 remember_string 將

大更新
我使用curses模塊而不是msvcrt (如最初建議的那樣)

這實際上存在與您類似的問題(非常簡化的模擬),
但解決了問題的核心

  1. 接收輸入
  2. 發生某事時刪除行並在該行中寫入消息
  3. 在那里重新輸入已經寫好的東西

只要輸入 <= 3 個字符,就需要輸入。
如果寫入 >= 4 個字符,它將執行 (3.) 對您來說完成查詢的內容,
然后用舊輸入再次要求輸入。
當按下 ENTER 時,完成輸入

import curses
import curses.ascii as ascii

def getch(stdscr: curses.window):
    'return single char'
    a = stdscr.get_wch()
    stdscr.refresh()
    return a

def prompt(stdscr: curses.window):
    'write prompt for input'
    addstr(stdscr, "Enter query: ")

def addstr(stdscr: curses.window, str):
    'write string to window'
    stdscr.addstr(str)
    stdscr.refresh()

def del_line(stdscr: curses.window):
    'deletes line in which cursor is'
    row, col = stdscr.getyx()
    stdscr.move(row, 0)
    stdscr.clrtoeol()

@curses.wrapper
def main(stdscr: curses.window):
    # next 3 lines were on some tutorial so I left them be
    # Clear screen
    stdscr.clear()
    curses.echo()

    # I will use marks like #x.y to indicate places
    q = ''
    while True: #EDIT from `for (5)` to `while`
        prompt(stdscr)
        addstr(stdscr, q) # at the beginning & after enter is pressed, q==''
                          # else it is old input (that was >= 4 chars
        for i in range(4): # range 4 to take 4 or less chars
            a = getch(stdscr) #read charby char
            if ascii.isalnum(a): #letters & numbers
                q += a
            elif a == '\n' or a == '\r': # enter pressed == input finished
                stdscr.addstr(f"\nfinished input {q}\n")
                q = ''
                break
        else: # this block happens (in py) if no break occurred in loop
            # that means, in this case, that ENTER was not pressed, i.e. input is stillongoing
            # but since it is > 4 chars it is briefly interrupted to write message
            del_line(stdscr)
            addstr(stdscr, "Input interupted\n")

    return 

測試
運行這個程序(我建議直接雙擊文件打開std終端,因為其他終端可能有針對這個[程序]的東西)
(E代表ENTER)
和類型: abcEabcdefEabcdefghijE
看看這是做什么的

附言

這可能會解決您的問題,但是此模塊的功能更大,
我不想寫太多復雜的 API。
解決方案是編寫 API 以便於管理更多的事情,比如用箭頭移動,但這不在這個問題的 scope

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM