2009-02-16 12 views
9

Tôi muốn sử dụng phiên bản con của Python 2.6, vì nó cho phép hàm Popen.terminate(), nhưng tôi bị mắc kẹt với Python 2.5. Có cách nào hợp lý để sử dụng phiên bản mới hơn của mô-đun trong mã 2.5 của tôi không? Một số loại from __future__ import subprocess_module?Sử dụng mô-đun con của Python 2.6 trong Python 2.5

+1

Popen.terminate() không làm việc đáng tin cậy , Tôi đã tìm thấy. Hãy cẩn thận. – Brandon

Trả lời

9

Tôi biết câu hỏi này đã được trả lời, nhưng đối với những gì nó có giá trị, tôi đã sử dụng subprocess.py mà tàu với Python 2,6 trong Python 2,3 và nó làm việc tốt. Nếu bạn đọc những ý kiến ​​ở phía trên cùng của tập tin nó nói:

# This module should remain compatible with Python 2.2, see PEP 291.

+2

PEP 291 rất hữu ích để biết. Cảm ơn! (liên kết, để thuận tiện cho người khác: http://www.python.org/dev/peps/pep-0291/) Tôi đã quyết định rằng câu trả lời của bạn trả lời câu hỏi của tôi chính xác hơn, mặc dù zacherates 'cũng rất hữu ích. – xyz

+2

Lưu ý: điều này không hoàn toàn đúng. Việc thực hiện tham số close_fds trong mô-đun subprocess 2.6 sử dụng os.closerange(), cái mới trong python 2.6 – itsadok

+0

này đã lưu lại ngày của tôi! cảm ơn bạn :-) –

0

Vâng Python là mã nguồn mở, bạn được tự do lấy hàm pthread đó từ 2.6 và di chuyển nó vào mã của riêng bạn hoặc sử dụng nó làm tham chiếu để thực hiện của riêng bạn.

Vì những lý do rõ ràng nên không có cách nào để kết hợp Python có thể nhập các phần của các phiên bản mới hơn.

6

Không thực sự là một cách tuyệt vời để làm điều đó. subprocess là implemented in python (trái ngược với C), do đó bạn có thể tưởng tượng sao chép mô-đun ở đâu đó và sử dụng nó (hy vọng tất nhiên là nó không sử dụng bất kỳ sự tốt lành 2.6 nào).

Mặt khác, bạn có thể thực hiện đơn giản những gì mà quy trình con yêu cầu thực hiện và viết một hàm gửi SIGTERM trên * nix và gọi TerminateProcess trên Windows. Việc thực hiện sau đây đã được thử nghiệm trên Linux và trong một Win XP vm, bạn sẽ cần 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) 

Bằng cách đó bạn chỉ cần duy trì mã terminate thay vì toàn bộ mô-đun.

+0

Tuyệt vời, cảm ơn rất nhiều! 'ps aux' nói với tôi rằng quá trình này không còn tồn tại sau khi kết thúc nó với hàm này, nhưng có vẻ như os.waitpid (process.pid, 0) sẽ xử lý nó. – xyz

2

Trong khi điều này không trực tiếp trả lời câu hỏi của bạn, điều đó có thể đáng được biết.

Nhập khẩu từ __future__ thực sự chỉ thay đổi tùy chọn trình biên dịch, vì vậy trong khi nó có thể chuyển thành câu lệnh hoặc tạo chuỗi ký tự sản xuất unicodes thay vì strs, nó không thể thay đổi khả năng và tính năng của mô-đun trong thư viện chuẩn Python.

+0

OK, cảm ơn. Tôi không biết điều đó. – xyz

1

Dưới đây là một số cách để kết thúc quá trình trên Windows, lấy trực tiếp từ 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) 
2

tôi theo sau Kamil Kisiel gợi ý về việc sử dụng python 2.6 subprocess.py trong python 2.5 và nó hoạt động hoàn hảo. Để làm cho nó dễ dàng hơn, tôi tạo ra một gói distutils mà bạn có thể easy_install và/hoặc bao gồm trong buildout.

Để sử dụng tiến trình con từ python 2,6 trong python 2.5 dự án:

easy_install taras.python26 

trong mã của bạn

from taras.python26 import subprocess 

trong buildout

[buildout] 
parts = subprocess26 

[subprocess26] 
recipe = zc.recipe.egg 
eggs = taras.python26