【问题标题】:Stopping a python process so that context managers still call __exit__ (in windows)停止 python 进程,以便上下文管理器仍然调用 __exit__ (在 Windows 中)
【发布时间】:2017-12-25 06:31:15
【问题描述】:

如何停止 python 进程,以使任何活动的上下文管理器在关闭之前优雅地调用其 __exit__ 函数?

我使用上下文管理器(__enter__() 和 __exit__())可靠且安全地关闭与光学硬件的连接。尽管我们现在开始执行运行数小时的例程,但这一直运行良好。通常我们会在启动一个程序后不久意识到我们有一个错误,并且宁愿停止这个过程。

我一直在运行 PyCharm 的代码,它允许您“停止”正在运行的进程。这似乎会立即终止进程,无论我是在调试还是运行。 __exit__ 函数似乎没有被调用。

此外,控制硬件的计算机也会运行 Windows,如果它以某种方式发挥作用的话。 ***

***确实在起作用。 Macosx 似乎调用了退出函数,而 windows 没有。

我决定写一个基本的测试:

from abc import *
import time

class Test(object):
    __metaclass__ = ABCMeta

    def __init__(self, *args, **kwargs):
        print("Init called.")

    def __enter__(self, *args, **kwargs):
        print("enter called")

    def __exit__(self, type, value, traceback):
        print("Exit called")

with Test() as t:
    time.sleep(100)
print("Should never get here.")

我从 PyCharm 运行这段代码,当它在睡眠语句中时,我按下 pycharm 中的停止按钮。这是两者的输出:

Macosx:

Init called.
enter called
Exit called
Traceback (most recent call last):
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1591, in <module>
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1018, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Users/.../Library/Preferences/PyCharmCE2017.1/scratches/scratch_25.py", line 22, in <module>
    time.sleep(100)
KeyboardInterrupt

窗户

Init called.
enter called

Process finished with exit code 1

【问题讨论】:

  • Control-C 如果在命令提示符下运行,它将起作用。
  • 我们目前从 PyCharm 运行,虽然我认为它可以让你调出某种终端。
  • 什么操作系统和Python版本?
  • __enter__ 方法定义包裹在try-except 周围并在except 子句中调用self.__exit__?我不是 PyCharm 使用的,但处理 KeyboardInterrupt 听起来不错。
  • 我可能完全错了。我刚刚制作了一个带有 time.sleep(100) 的基本上下文管理器。当我点击 PyCharm 中的停止按钮时,它会调用退出函数。

标签: python windows


【解决方案1】:

我在 PyCharm 错误跟踪器上找到了解决方法:

https://youtrack.jetbrains.com/issue/PY-17252

  • 在 PyCharm 中转到帮助->编辑自定义属性
  • 同意创建 idea.properties 文件(如果需要)
  • 添加以下行:kill.windows.processes.softly=true
  • 如果您使用 Numpy 或 Scipy,您还需要添加以下环境变量:

    os.environ['FOR_DISABLE_CONSOLE_CTRL_HANDLER'] = "1"

  • 重启 Pycharm

现在,当我使用此应用程序运行测试时(在 Windows 上!),我得到以下输出:

Init called.
enter called
Exit called
Traceback (most recent call last):
  File "C:/Users/.../.PyCharmCE2017.1/config/scratches/scratch_3.py", line 20, in <module>
    time.sleep(100)
KeyboardInterrupt

Process finished with exit code 1

【讨论】:

    猜你喜欢
    • 2017-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-28
    • 2016-11-04
    相关资源
    最近更新 更多