python停止循环代码,如何在Python中安全地停止无限循环?

I've got a script that runs on a infinite loop and adds things to a database and does things that I can't just stop halfway through so I can't just press ctrl+C and stop it.

I want to be able to somehow stop a while loop but let it finish it's last iteration before it stops.

Let me clarify:

my code looks something like this:

while True:

does something

does more things

does more things

I want to be able to interrupt the while loop at the end, or the beginning, but not between doing things because that would be bad.

and I don't want it to ask me after every iteration if i want to continue.

thanks for the great answers, i'm super grateful but my implementation doesn't seem to be working:

def signal_handler(signal, frame):

global interrupted

interrupted = True

class Crawler():

def __init__(self):

# not relevent

def crawl(self):

interrupted = False

signal.signal(signal.SIGINT, signal_handler)

while True:

doing things

more things

if interrupted:

print("Exiting..")

break

when I press ctr+c the program just keeps going ignoring me

解决方案

What you need to do is catch the interrupt, set a flag saying you were interrupted but then continue working until it's time to check the flag (at the end of each loop). Because python's try-except construct will abandon the current run of the loop, you need to set up a proper signal handler; it'll handle the interrupt but then let python continue where it left off. Here's how:

import signal

import time # For the demo only

def signal_handler(signal, frame):

global interrupted

interrupted = True

signal.signal(signal.SIGINT, signal_handler)

interrupted = False

while True:

print("Working hard...")

time.sleep(3)

print("All done!")

if interrupted:

print("Gotta go")

break

Notes:

Use this from the command line. In the IDLE console, it'll trample on IDLE's own interrupt handling.

A better solution would be to "block" KeyboardInterrupt for the duration of the loop, and unblock it when it's time to poll for interrupts. This is a feature of some Unix flavors but not all, hence python does not support it (see the third "General rule")

The OP wants to do this inside a class. But the interrupt function is invoked by the signal handling system, with two arguments: The signal number and a pointer to the stack frame-- no place for a self argument giving access to the class object. Hence the simplest way to set a flag is to use a global variable. You can rig a pointer to the local context by using closures (i.e., define the signal handler dynamically in __init__(), but frankly I wouldn't bother unless a global is out of the question due to multi-threading or whatever.

Caveat: If your process is in the middle of a system call, handling an signal may interrupt the system call. So this may not be safe for all applications. Safer alternatives would be (a) Instead of relying on signals, use a non-blocking read at the end of each loop iteration (and type input instead of hitting ^C); (b) use threads or interprocess communication to isolate the worker from the signal handling; or (c) do the work of implementing real signal blocking, if you are on an OS that has it. All of them are OS-dependent to some extent, so I'll leave it at that.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值