我想使用 Python 2.6 的子进程版本,因为它允许Popen.terminate()函数,但我坚持使用 Python 2.5。在我的 2.5 代码中是否有一些相当干净的方法来使用模块的较新版本?某种from __future__ import subprocess_module
?
6 回答
我知道这个问题已经得到了回答,但是对于它的价值,我已经subprocess.py
在 Python 2.3 中使用了 Python 2.6 附带的那个,它运行良好。如果您阅读文件顶部的评论,它会说:
# This module should remain compatible with Python 2.2, see PEP 291.
真的没有一个很好的方法来做到这一点。subprocess 是在 python 中实现的(而不是 C),因此您可以想象将模块复制到某处并使用它(当然希望它不使用任何 2.6 的优点)。
另一方面,您可以简单地实现子进程声称要做的事情,并编写一个在 *nix 上发送 SIGTERM 并在 Windows 上调用 TerminateProcess 的函数。以下实现已经在 linux 和 Win XP vm 上进行了测试,您需要python Windows 扩展:
import sys
def terminate(process):
"""
Kills a process, useful on 2.5 where subprocess.Popens don't have a
terminate method.
Used here because we're stuck on 2.5 and don't have Popen.terminate
goodness.
"""
def terminate_win(process):
import win32process
return win32process.TerminateProcess(process._handle, -1)
def terminate_nix(process):
import os
import signal
return os.kill(process.pid, signal.SIGTERM)
terminate_default = terminate_nix
handlers = {
"win32": terminate_win,
"linux2": terminate_nix
}
return handlers.get(sys.platform, terminate_default)(process)
这样你只需要维护terminate
代码而不是整个模块。
虽然这不能直接回答您的问题,但可能值得了解。
Imports from__future__
实际上只会更改编译器选项,因此虽然它可以将 with 转换为语句或使字符串文字生成 unicode 而不是 strs,但它不能更改 Python 标准库中模块的功能和特性。
我遵循了关于在 python 2.5 中使用 python 2.6 subprocess.py 的 Kamil Kisiel 建议,并且效果很好。为了使它更容易,我创建了一个 distutils 包,您可以轻松安装和/或包含在 buildout 中。
要在 python 2.5 项目中使用来自 python 2.6 的子进程:
easy_install taras.python26
在你的代码中
from taras.python26 import subprocess
在扩建中
[buildout]
parts = subprocess26
[subprocess26]
recipe = zc.recipe.egg
eggs = taras.python26
以下是在 Windows 上结束进程的一些方法,直接取自 http://code.activestate.com/recipes/347462/
# Create a process that won't end on its own
import subprocess
process = subprocess.Popen(['python.exe', '-c', 'while 1: pass'])
# Kill the process using pywin32
import win32api
win32api.TerminateProcess(int(process._handle), -1)
# Kill the process using ctypes
import ctypes
ctypes.windll.kernel32.TerminateProcess(int(process._handle), -1)
# Kill the proces using pywin32 and pid
import win32api
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, process.pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)
# Kill the proces using ctypes and pid
import ctypes
PROCESS_TERMINATE = 1
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, process.pid)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)
好吧,Python 是开源的,您可以自由地从 2.6 中获取该 pthread 函数并将其移动到您自己的代码中,或者将其用作实现您自己的代码的参考。
出于显而易见的原因,没有办法拥有可以导入部分较新版本的 Python 混合体。