Vorrei utilizzare la versione di sottoprocesso di Python 2.6, perché consente la funzione Popen.terminate(), ma sono bloccato con Python 2.5. C'è un modo abbastanza pulito per utilizzare la versione più recente del modulo nel mio codice 2.5? Una specie di from __future__ import subprocess_module
?Utilizzare il sottoprocesso Python 2.6 in Python 2.5
risposta
So che questa domanda ha già avuto risposta, ma per quello che vale, ho usato il subprocess.py
fornito con Python 2.6 in Python 2.3 e ha funzionato bene. Se leggete i commenti nella parte superiore del file che dice:
# This module should remain compatible with Python 2.2, see PEP 291.
PEP 291 è molto utile sapere. Grazie! (link, per comodità degli altri: http://www.python.org/dev/peps/pep-0291/) Ho deciso che la tua risposta risponde alla mia domanda in modo più preciso, anche se gli zacherati sono anche molto utili. – xyz
Avvertenza: questo non è proprio vero. L'implementazione del parametro close_fds nel modulo subprocess 2.6 utilizza os.closerange(), che è nuovo in python 2.6 – itsadok
questo mi ha salvato la giornata! grazie :-) –
Bene Python è open source, sei libero di prendere quella funzione di pthread dalla 2.6 e spostarla nel tuo codice o usarla come riferimento per implementare la tua.
Per motivi che dovrebbero essere ovvi, non c'è modo di avere un ibrido di Python in grado di importare porzioni di versioni più recenti.
Non c'è davvero un ottimo modo per farlo. il sottoprocesso è implemented in python (in contrapposizione a C), quindi è possibile copiare il modulo da qualche parte e usarlo (sperando ovviamente che non usi nessuna bontà 2.6).
D'altra parte si potrebbe semplicemente implementare quali richieste di sottoprocesso fare e scrivere una funzione che invia SIGTERM su * nix e chiama TerminateProcess su Windows. La seguente applicazione è stata testata su Linux e in un Win XP VM, è necessario il python Windows extensions:
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)
In questo modo si hanno solo a mantenere il codice terminate
piuttosto che l'intero modulo.
Fantastico, grazie mille! 'ps aux' mi dice che il processo è defunto dopo averlo terminato con questa funzione, ma sembra che os.waitpid (process.pid, 0) si prenda cura di questo. – xyz
Mentre questo non risponde direttamente alla tua domanda, potrebbe valerne la pena.
Le importazioni da __future__
cambiano in realtà solo le opzioni del compilatore, quindi mentre può trasformare in un'istruzione o fare in modo che le stringhe producano unicode anziché strs, non può modificare le funzionalità e le funzionalità dei moduli nella libreria standard Python.
Capito, grazie. Non lo sapevo. – xyz
Ecco alcuni modi per terminare i processi su Windows, presi direttamente dal 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)
I seguito il suggerimento di Kamil Kisiel sull'utilizzo di python 2.6 subprocess.py in python 2.5 e ha funzionato perfettamente. Per semplificare, ho creato un pacchetto distutils che puoi installare easy_install e/o includere in buildout.
Per utilizzare il sottoprocesso da Python 2.6 in Python 2.5 progetto:
easy_install taras.python26
nel codice
from taras.python26 import subprocess
in buildout
[buildout]
parts = subprocess26
[subprocess26]
recipe = zc.recipe.egg
eggs = taras.python26
Popen.terminate() non funziona in modo affidabile , Ho trovato. Stai attento. – Brandon