Python'u basılı bir tuş için nasıl bekletirim?


571

Komut dosyamın kullanıcı herhangi bir tuşa basmasını beklemesini istiyorum.

Bunu nasıl yaparım?

Yanıtlar:


543

In Python 3 kullanım input():

input("Press Enter to continue...")

In Python 2 kullanım raw_input():

raw_input("Press Enter to continue...")

Bu sadece kullanıcının enter tuşuna basmasını bekler.

Biri msvcrt kullanmak isteyebilir ((yalnızca Windows / DOS) msvcrt modülü, Microsoft Visual C / C ++ Çalışma Zamanı Kitaplığı'nda (MSVCRT) bir dizi işleve erişmenizi sağlar:

import msvcrt as m
def wait():
    m.getch()

Bu bir tuşa basmayı beklemelidir.

İlave bilgi:

Python 3'te raw_input()mevcut değil

Python 2'de input(prompt)eşdeğerdireval(raw_input(prompt))


54
Bunu Python 2.7'de yapmaya çalıştığımda bu hatayı alıyorum: "SyntaxError: ayrıştırma sırasında beklenmedik EOF"
Jon Tirsen

8
@ Solarsaturn9 ve artan ve çok sayıda değil. Böylece bu cevap benim için ve buraya gelen pek çok kişi için işe yaramadı.
ctrl-alt-delor

5
@richard input () kullanarak diğer platformlarda da çalışmalıdır. İlk çözüm çok platformlu olduğunda yalnızca alternatif bir Windows çözümü sağlamak için puan almak çok saçma.
Cory Buckley

7
@ Solarsaturn9 soruyu okuyun ve tekrar cevaplayın: inputherhangi bir tuşa basıldığında devam etmez, yalnızca enter tuşuna basıldığında devam etmez.
ctrl-alt-delor

13
@JonTirsen, çünkü Python 2.7'nin girdiğiniz dizeyi değerlendiren giriş adı verilen bir işlevi vardır. Düzeltmek için raw_input komutunu kullanın
Samy Bencherif

316

Bunu Python 2'de yapmanın bir yolu kullanmaktır raw_input():

raw_input("Press Enter to continue...")

Python3'te sadece input()


17
Ne zaman birkaç anahtardan biri olabilir? Sadece değil entermi?
noio

33
Python 3+ ile bu sadece olarak değişti input().
palswim

Py2 ve Py3 uyumlu kod için altı kullanma :from six.moves import input; input("Press Enter to continue...")
rcoup

56

Linux kutumda aşağıdaki kodu kullanıyorum. Bu, başka bir yerde gördüğüm koda benzer (örneğin eski python SSS'lerinde), ancak bu kod bu kodun olmadığı sıkı bir döngüde döner ve kodun bunu hesaba katmadığı çok sayıda tek köşe vakası vardır kod yapar.

def read_single_keypress():
    """Waits for a single keypress on stdin.

    This is a silly function to call if you need to do it a lot because it has
    to store stdin's current setup, setup stdin for reading single keystrokes
    then read the single keystroke then revert stdin back after reading the
    keystroke.

    Returns a tuple of characters of the key that was pressed - on Linux, 
    pressing keys like up arrow results in a sequence of characters. Returns 
    ('\x03',) on KeyboardInterrupt which can happen when a signal gets
    handled.

    """
    import termios, fcntl, sys, os
    fd = sys.stdin.fileno()
    # save old state
    flags_save = fcntl.fcntl(fd, fcntl.F_GETFL)
    attrs_save = termios.tcgetattr(fd)
    # make raw - the way to do this comes from the termios(3) man page.
    attrs = list(attrs_save) # copy the stored version to update
    # iflag
    attrs[0] &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK
                  | termios.ISTRIP | termios.INLCR | termios. IGNCR
                  | termios.ICRNL | termios.IXON )
    # oflag
    attrs[1] &= ~termios.OPOST
    # cflag
    attrs[2] &= ~(termios.CSIZE | termios. PARENB)
    attrs[2] |= termios.CS8
    # lflag
    attrs[3] &= ~(termios.ECHONL | termios.ECHO | termios.ICANON
                  | termios.ISIG | termios.IEXTEN)
    termios.tcsetattr(fd, termios.TCSANOW, attrs)
    # turn off non-blocking
    fcntl.fcntl(fd, fcntl.F_SETFL, flags_save & ~os.O_NONBLOCK)
    # read a single keystroke
    ret = []
    try:
        ret.append(sys.stdin.read(1)) # returns a single character
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save | os.O_NONBLOCK)
        c = sys.stdin.read(1) # returns a single character
        while len(c) > 0:
            ret.append(c)
            c = sys.stdin.read(1)
    except KeyboardInterrupt:
        ret.append('\x03')
    finally:
        # restore old state
        termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
    return tuple(ret)

Bu, buradaki cevapların favorisi olsa da, diğerleri gibi vardiya, kontrol vb. Şeyleri yakalamıyor
Mala

1
@ Saf Python'da neredeyse mümkün olmayan Mala; belki bir C modülü yazmalısınız?
kedi

Sistemimde klavye kesilmesinde (Ctrl-C) "\ x03" alıyorum.
GDR

1
ctrl-c bir ascii 3 olduğundan beklenen bir durumdur. Ctrl-c üzerinde bir sinyal yükseltmek istiyorsanız, kolay çözüm bir if ord (return_value) == 3: os.kill (os.getpid (), signal.SIGINT) koymaktır, ancak sinyal işlemeyi de kapatabilirsiniz attrs [0] | = termios.BRKINT, attrs [3]! = termios.ISIG ve dışında KeyboardInterrupt işleminden kurtulun. Not - KeyboardInterrupt için dönüş değerini sorgunuzun onuruna bir '\ x03' olarak değiştirdim (ve bu kod her zaman bir dize döndürdüğünden).
mheyman

Yukarıdaki kod, "Sayfa Yukarı" veya "Sol Ok" gibi karmaşık bir tuş basımı için bir demet döndürecek şekilde nasıl ayarlanabilir?
Derek

33

Sistem komutlarına bağlı olarak sorun yaşıyorsanız aşağıdakileri kullanabilirsiniz:

Linux:

import os
os.system('read -sn 1 -p "Press any key to continue..."')
print

Pencereler:

import os
os.system("pause")

Bir sinyal yükseltilene kadar (SIGINT gibi) çalışmaya devam etmek istiyorsanız, dönüş değerini kontrol edebilir systemve sonra arayabilirsiniz sys.exit(0).
James Taylor

29

Sadece

input("Press Enter to continue...")

bir SyntaxError: ayrıştırma sırasında beklenen EOF'ye neden olur.

Basit düzeltme kullanımı:

try:
    input("Press enter to continue")
except SyntaxError:
    pass

5
inputPython 2'de kullanmayın - doğru işlev raw_input. Python 2'de, buna inputeşdeğerdir eval(raw_input()).
Blorgbeard

2
Bu, kullanıcının enter tuşuna basana kadar OP'nin istediklerinden oldukça farklı olan tüm tuşlarını yok sayar.
Jonathan Hartley

1
Ayrıca, 'input' kullanacaksanız, bir SyntaxError yakalamak uygun değildir. Kullanıcı türleri ne şekilde değerlendirilirse değerlendirilsin, örneğin "1/0" yazarlarsa SyntaxError yerine ZeroDivisionError oluşturulur ve programınızdan çıkılır.
Jonathan Hartley

@Blorgbeard'ın belirttiği gibi, sadece raw_input ("Devam etmek için Enter tuşuna basın") kullanmak yeterli olacaktır. Hata ayıklama sırasında sık sık kullanıyorum.
alltrue

15

Python kılavuzu aşağıdakileri sağlar:

import termios, fcntl, sys, os
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", repr(c)
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

kullanım durumunuza yuvarlanabilir.


12
Bağlantınız olan şeyi kopyalamak iyi bir uygulamadır, böylece bağlantı kopsa bile (ve yaparlar!) Bilgi kalır.
Richard

1
Bunu Python 3.x ile nasıl çalıştırabilirim? 3.x'te, print ifadesini uyumlu olacak şekilde değiştirdikten sonra, bu sadece sonsuz bir şekilde döngüye girer ve girdi için beklemez. Yine de Python 2'de harika çalışıyor.
kedi

Bağlantı, farklı bir sayfaya yönlendirilecek şekilde güncellendi. Yeni bağlantı burada.
Matthias

15

Çapraz Platform, Python 2/3 kodu:

# import sys, os

def wait_key():
    ''' Wait for a key press on the console and return it. '''
    result = None
    if os.name == 'nt':
        import msvcrt
        result = msvcrt.getch()
    else:
        import termios
        fd = sys.stdin.fileno()

        oldterm = termios.tcgetattr(fd)
        newattr = termios.tcgetattr(fd)
        newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
        termios.tcsetattr(fd, termios.TCSANOW, newattr)

        try:
            result = sys.stdin.read(1)
        except IOError:
            pass
        finally:
            termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)

    return result

Ben IOErrors verdi ve ben gerek yoktu çünkü fctl / engelleme olmayan şeyler kaldırıldı . Bu kodu özellikle engellemek istiyorum çünkü kullanıyorum. ;)

Zeyilname:

Bunu, konsol adı verilen pek çok başka şeyle PyPI'deki bir pakette uyguladım :

>>> from console.utils import wait_key

>>> wait_key()
'h'

1
Hata aldım: Cihaz için uygunsuz ioctl '
Benoit

@ Hangi işletim sistemi?
Gringo Suave

Linux - Ubuntu 20.04
Benoit

14

Bunu yapmanın platformdan bağımsız bir yolunu bilmiyorum, ancak Windows altında, msvcrt modülünü kullanıyorsanız, getch işlevini kullanabilirsiniz:

import msvcrt
c = msvcrt.getch()
print 'you entered', c

mscvcrt ayrıca bir tuşa beklemeden basıldığını görmek için engellemeyen kbhit () işlevini de içerir (karşılık gelen bir lanetler işlevi olup olmadığından emin değilsiniz). UNIX altında, curses paketi var, ancak tüm ekran çıktısı için kullanmadan kullanıp kullanamayacağınızdan emin değilsiniz. Bu kod UNIX altında çalışır:

import curses
stdscr = curses.initscr()
c = stdscr.getch()
print 'you entered', chr(c)
curses.endwin()

Curses.getch () 'in, basmam gereken aynı çıktıya sahip olması için basılan anahtarın sırasını döndürdüğünü unutmayın.


Lanetler kullanmak, büyük bir bağımlılık içeriyor olsa bile, kılavuzda açıklanan oldukça kıvrık örneklerden çok daha güzel. +1
Damian

4

Enter'ı beklemek istiyorsanız (böylece klavyeyi kullanan kullanıcı amaçlanmayan bir şeyin olmasına neden olmaz) kullanın

sys.stdin.readline()

2
Bütün mesele, kullanıcının sadece Enter tuşuna basması gerekmemesi, örneğin boşluk çubuğunu tokatlamak. İstenmeyen bir şeyin olmasını önlemek için Enter'a ihtiyacınız varsa, bu kötü bir tasarımdır.
Synetech

3

Python'da yeniyim ve zaten burada yapılan en basit önerileri çoğaltmak için çok aptal olduğumu düşünüyordum. Anlaşılan, kişinin bilmesi gereken bir tuzak var:

IDLE'den bir python betiği yürütüldüğünde, bazı IO komutları tamamen farklı gibi görünür (aslında terminal penceresi olmadığı için).

Örneğin. msvcrt.getch engellemez ve her zaman $ ff döndürür. Bu uzun zaman önce bildirildi (bkz. Örneğin https://bugs.python.org/issue9290 ) - ve sabit olarak işaretlendi, sorun bir şekilde python / IDLE'nin mevcut sürümlerinde devam ediyor gibi görünüyor.

Bu nedenle, yukarıda yayınlanan kodlardan herhangi biri sizin için işe yaramazsa, komut dosyasını IDLE'den DEĞİL manuel olarak çalıştırmayı deneyin .


0

Tam bir tuşa basıp basmadıklarını görmek istiyorsanız ('b' demek gibi) Bunu yapın:

while True:
    choice = raw_input("> ")

    if choice == 'b' :
        print "You win"
        input("yay")
        break

8
Bu, kullanıcının 'b' (veya başka bir şey) yazmasını ve ardından OP'nin istediğinden oldukça farklı olan enter tuşuna basmasını gerektirir.
Jonathan Hartley

0

os.system her zaman okumak için s ve n seçeneklerini tanımayan sh'yi çağırır. Ancak okuma komutu bash'a iletilebilir:

 os.system("""bash -c 'read -s -n 1 -p "Press any key to continue..."'""")

2
-T seçeneğini belirtmedikçe, okuma belgeleri zaman aşımına uğramayacağını düşündürüyor.
James King
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.