Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
quasi permant läuft. Per STRG+C kann man das ja beenden nun möchte ich aber vorher eine Art Sicherheitsabfrage einbauen à la: "Wollen Sie wirklich beenden? (N/j)"
Falsche Schachtelung. Wenn die Ausnahme ausserhalb der Schleife behandelt wird, führt kein Weg mehr in die Schleife hinein. Du musst innerhalb der Schleife behandeln und wenn der Benutzer beenden will die Schleife zum Beispiel mit ``break`` abbrechen.
import string
while True:
try:
print "Laufe durch und tue dies"
print "Laufe durch und tue und das"
print "Laufe durch und tue und jenes"
print "Laufe durch und tue noch viel mehr"
except KeyboardInterrupt:
while True:
confirm = raw_input('Enter "yes" to cancel or "no" to keep running [yes/no]:').strip().lower()
if confirm == 'yes':
print "Cancel!"
break
elif confirm == 'no':
print "Keep runnning!"
pass
else:
print ('Sorry, no valid answer...')
pass
print "Draussen"
Das klappt aber noch nicht so richtig. Was mir gerade dazu eingefallen ist, nach Auslösen des KeyboardInterruptes und Beantwortung mit "Nein, soll weiterlaufen" wird dann an der Stelle weitergemacht wo das Programm vorher stand? Oder fängt die Schleife dann wieder komplett neu an?
Ich möchte also einfach sicherstellen das der Benutzer nicht aus Versehen das Programm stoppt - im Fall des Falles (doch mal STRG-C gedrückt) soll es aber einfach weitermachen. Geht das dann überhaupt? Oder brauche ich einen ganz anderen Ansatz. Das ganze ist ein Task, der halt die ganze Zeit quasi im Hintergrund laufen sollte aber ab und an sind die Konsolenausgaben wichtig.
wird der interrupt ausgelöst, so wird aus dem try-block rausgesprungen.
hier würde dann also (falls der nutzer das so will) ein neuer schelifendurchlauf gestartet werden.
du musst dann also im except block (oder in finally) sicherstellen, dass das programm in einem definierten (vernünftigen) zustand ist.
zu deinem code: überleg mal was bei dem break bei cancel passiert ...
Mhmm, ok. Dann hilft mir dieser Ansatz nicht unbedingt weiter. Gibt es keine Möglichkeit die Unterbrechung vorher abzufangen? Also bevor "unterbrochen" wird?
zu deinem code: überleg mal was bei dem break bei cancel passiert ...
Ok, das break springt zurück in die while Schleife. Das will ich natürlich nicht. Also dann besser das Programm mit exit() beenden?
@der_dan: Du solltest vielleicht an die Quelle gehen und verhindern dass das entsprechende Signal vom Betriebssystem an den Prozess nicht ausgewertet wird. Geht vielleicht mit dem `signal`-Modul.
Grundsätzlich halte ich das für keine gute Idee. Programme die sich nicht mit SIGINT abbrechen lassen und mich zwingen `ps` und `kill` oder `killall` zu bemühen, finde ich jedenfalls ziemlich nervig.
Tja, da treffen wohl asynchrone Signalbehandlung in C und ein Interpreter unglücklich aufeinander. Wahrscheinlich wird auf dieses Signal nur bei bestimmten Bytecode-Befehlen geprüft um es in eine Ausnahme umzuwandeln und bei so grundlegende Sachen wie Sprungbefehlen wird nicht geprüft um Schleifen nicht auszubremsen. Und wenn in der Schleife "nichts" gemacht wird, wird halt auch nicht auf das Signal geprüft.
Wenn es stört, sollte man vielleicht einen Bug-Report absetzen.
BlackJack hat geschrieben:@der_dan: Du solltest vielleicht an die Quelle gehen und verhindern dass das entsprechende Signal vom Betriebssystem an den Prozess nicht ausgewertet wird.
Danke für den Tipp! Das werde ich mir mal ansehen. Wie du schon geschrieben hast ist das natürlich ziemlich brachial
Ansonsten werde ich wohl den Code entsprechend umstellen und das ganze irgendwie als Hintergrundprozess realsieren und den Rest irgendwie über eine Art "logging" abbilden.
import string
import signal
import sys
import itertools
from time import sleep
def onexit(signum, handler):
print('STRG+C pressed! (Signal: %s)' % (signum,))
while True:
confirm = raw_input('Enter "yes" to cancel programm now or "no" to keep running [yes/no]:').strip().lower()
if confirm == 'yes':
print "Cancel!"
sys.exit()
elif confirm == 'no':
print "Keep runnning!"
break
else:
print ('Sorry, no valid answer...')
pass
signal.signal(signal.SIGINT, onexit)
counter = itertools.count()
# Angenommen hier wäre mein eigentliches Programm
while True:
print counter.next()
sleep(2)
Ist scheinbar das, was ich gesucht habe. Zumindest läuft der "Simulations-Counter", der mein Programm darstellen soll an der Stelle weiter wo ich ihn erwarte. Vielleicht übersehe ich auf Grund meiner leider noch begrenzten Python Kenntnisse allerdings etwas? Wie sieht es mit Threads aus? Kann ich das so machen? Was meint ihr?
sorry, wenn ich den nochmal rauskrame aber ich bin diesbezüglich leider noch nicht weiter...
Mir gehts darum: Wird die Ausführung des Programms inkl. aller Threads nach dem SIGINT / STRG+C "angehalten/eingefroren" oder laufen die Threads im Hintergrund einfach weiter und sobald ich dann den Abbruch bestätige bin ich "irgendwo" im Code?