【问题标题】:Send a variable from outside the python console OR stop a script from outside从 python 控制台外部发送变量或从外部停止脚本
【发布时间】:2016-11-06 21:50:11
【问题描述】:

我编写了一个 Python 脚本,该脚本执行优化并运行数天以获得解决方案(由于目标函数成本高昂)。在所有的工作中,只要在某个时候停止计算就足够了,因为解决方案对我来说已经足够好了(但对于优化算法来说却不是)。

问题是,我总是可以中止按 Ctrl+C。但是没有机会很好地输出当前的最佳参数,绘制数据,保存它等等。在下一次计算目标函数之后以受控方式停止脚本会很棒。所以我的想法是质疑一些变量(如果 user_stop=True)并以编程方式停止优化。但是如何设置这样的变量呢? python控制台在执行过程中被阻塞。

我考虑过设置文本文件的内容并在每次迭代中读取它,但对于脚本的其他用户来说,这不仅糟糕而且难以解释。从理论上讲,我也可以要求用户输入,但脚本不会自动运行(它应该直到有人决定停止)。

对我的问题有什么想法吗?

基本上就是这样 - 在某个点停止循环但执行打印:

a = 0
while True:
    a = a + 1
print(a)

【问题讨论】:

  • 在正在运行的进程中插入或更改变量是非常不安全的,而且非常困难。调试器会这样做,这就是您必须采取的方法(在旧版本的 Windows 中,可以进行 DLL 接种,但在最近的版本中这是有问题的)。您在哪个操作系统上运行?
  • 查看signals 模块。您可以从进程外部发送一个信号,您的进程可以捕获它,并且可以在调用 sys.exit(..) 之前将所有参数写入您的文件。
  • 我在 Windows 7 上运行。我查看了信号模块,根据这里的很多线程,它似乎比 Windows 上的解决方案更麻烦。我担心这不会是我的首选解决方案。但是,如果没有其他人出现,我会尝试一下。

标签: python


【解决方案1】:

如果您不经常轮询“变量”(比如最多每 20 秒一次),那么测试文件的开销可以忽略不计。类似的东西

import os
QUITFILE = "/home/myscript/quit_now.txt"
# and for convenience, delete any old QUITFILE that may exist at init time

...  # days later 
if os.path.isfile( QUITFILE) 
    # tidy up, delete QUITFILE, and exit

然后只需echo please > home/myscript/quit_now.txt 告诉您的程序退出。

【讨论】:

  • 是的,这就是我已经想到的解决方案。但是,在将脚本交给 colleques 时,最好说“按 q 或 Esc 停止”而不是“在此特定文件夹中创建文件 quit_now.txt”... ;)
  • 那么,作弊。分离脚本(linux command &)并将您同事的终端连接到另一个程序,该程序将检测q 或其他任何程序,并在检测到时创建quit_now.txt。不确定 Windows 等效项,但必须有一个。
  • 好主意!那会很有问题。成为当下要做的事情。
【解决方案2】:

也许您可以使用 do-while 循环。将目标保存在变量中 在循环之外并开始循环计算 while

【讨论】:

    【解决方案3】:

    对于 Windows,我会使用 msvcrt.getch()

    例如,此脚本将循环直到按下某个键,然后,如果是q,则提示用户退出:(注意if 语句使用'short circuiting' 仅评估@987654328 @ - 阻塞 - 当我们知道某个键被按下时。)

    import msvcrt, time
    
    while True: #This is your optimization loop
        if msvcrt.kbhit() and msvcrt.getch() == 'q':
            retval = raw_input('Quit? (Y/N) >')
            if retval.lower() == 'y':
                print 'Quitting'
                break #Or set a flag...
        else:
            time.sleep(1)
            print('Processing...')
    

    如果您将此if 块放置在优化循环中将经常运行的某个点,它将允许您在方便的点进行操作,或者至少设置一个您可以在最后检查的标志每次优化运行。

    如果你不能把它放在经常被检查的地方,那么你可以看看处理 Ctrl-C 引发的KeyboardInterrupt

    如果您在 Linux 上运行,或者需要跨平台功能,请查看this 获取按键的答案。

    【讨论】:

    • 这将是一个很棒的解决方案,我真的很喜欢。但是,当我按下任何键时,什么都没有发生。 msvcrt.kbhit() 总是返回 False,无论窗口焦点在哪里。我在 Windows 7 中运行,Anaconda+IPython ......也许后者是问题所在 - 但是:有没有办法仍然有效?跨度>
    • 奇数。我想它可能是 Anaconda / IPython。 [这里](ithub.com/ContinuumIO/anaconda-issues/issues/202) 是一篇文章,提到 Anaconda 只附带旧版本的 DLL,但我不认为这会是个问题。要清楚 - 上面的代码作为独立脚本运行不起作用? (在我的 Win 7 机器上工作)
    • 它在命令行中使用 python 和 ipython 工作。但不幸的是不在 Anaconda 内。
    • 真可惜。在这种情况下,最好的办法是查看处理 CTRL-C 或 SuperSaiyan 上面建议的信号模块。
    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 2018-08-14
    相关资源
    最近更新 更多