2011-10-13 16 views
8

Tôi đang làm việc để nhúng Python vào ứng dụng bộ thử nghiệm của mình. Mục đích là sử dụng Python để chạy một số kịch bản lệnh kiểm tra để thu thập dữ liệu và tạo báo cáo kiểm tra. Nhiều kịch bản thử nghiệm cho một lần chạy thử nghiệm có thể tạo các biến và hàm chung có thể được sử dụng trong tập lệnh tiếp theo.Làm cách nào để khởi động lại trình thông dịch Python được nhúng?

Ứng dụng này cũng cung cấp các mô đun mở rộng được nhập trong trình thông dịch được nhúng và được sử dụng để trao đổi một số dữ liệu với ứng dụng.

Nhưng người dùng cũng có thể thực hiện nhiều lần chạy thử. Tôi không muốn chia sẻ những hình ảnh tổng thể, nhập khẩu và dữ liệu trao đổi giữa nhiều lần chạy thử nghiệm. Tôi phải chắc chắn rằng tôi khởi động lại ở trạng thái chính hãng để kiểm soát môi trường thử nghiệm và nhận được kết quả tương tự.

Tôi nên khởi động lại trình thông dịch như thế nào?

Tôi đã sử dụng Py_Initialize() và Py_Finalize(), nhưng có ngoại lệ khi chạy lần thứ hai khi khởi tạo lần thứ hai các mô đun mở rộng mà tôi cung cấp cho trình thông dịch. Và tài liệu warns against using it more than once.

Sử dụng sub-interpreters dường như có cùng cảnh báo với việc khởi tạo mô-đun mở rộng.

Tôi nghi ngờ rằng tôi đang làm điều gì đó sai với việc khởi tạo các mô-đun mở rộng của mình, nhưng tôi lo ngại rằng vấn đề tương tự cũng xảy ra với các mô-đun mở rộng của bên thứ ba.

Có thể làm cho nó hoạt động bằng cách khởi chạy trình thông dịch trong quá trình riêng của nó, để đảm bảo rằng tất cả bộ nhớ được giải phóng.

Nhân tiện, tôi đang sử dụng tăng-python cho nó, nó cũng cảnh báo CHỐNG LẠI bằng cách sử dụng Py_Finalize!

Bất kỳ đề xuất nào?

Cảm ơn

Trả lời

4

Đây là một cách khác tôi tìm thấy để đạt được những gì tôi muốn, bắt đầu với một phương tiện sạch trong phiên dịch.

tôi có thể kiểm soát không gian tên toàn cầu và địa phương tôi sử dụng để thực thi mã:

// get the dictionary from the main module 
// Get pointer to main module of python script 
object main_module = import("__main__"); 
// Get dictionary of main module (contains all variables and stuff) 
object main_namespace = main_module.attr("__dict__"); 

// define the dictionaries to use in the interpreter 
dict global_namespace; 
dict local_namespace; 

// add the builtins 
global_namespace["__builtins__"] = main_namespace["__builtins__"]; 

sau đó tôi có thể sử dụng sử dụng không gian tên để thực hiện các mã chứa trong pyCode:

exec(pyCode, global_namespace, lobaca_namespace); 

tôi có thể làm sạch không gian tên khi tôi muốn chạy một phiên bản mới của thử nghiệm của tôi, bằng cách làm sạch các từ điển:

// empty the interpreters namespaces 
global_namespace.clear(); 
local_namespace.clear();   

// Copy builtins to new global namespace 
global_namespace["__builtins__"] = main_namespace["__builtins__"]; 

Tùy thuộc vào cấp độ nào tôi muốn thực thi, tôi có thể sử dụng global = local

0

Cách sử dụng code.IteractiveInterpreter?

Something như thế này nên làm điều đó:

#include <boost/python.hpp> 
#include <string> 
#include <stdexcept> 

using namespace boost::python; 

std::string GetPythonError() 
{ 
    PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; 
    PyErr_Fetch(&ptype, &pvalue, &ptraceback); 
    std::string message(""); 
    if(pvalue && PyString_Check(pvalue)) { 
     message = PyString_AsString(pvalue); 
    } 
    return message; 
} 

// Must be called after Py_Initialize() 
void RunInterpreter(std::string codeToRun) 
{ 
    object pymodule = object(handle<>(borrowed(PyImport_AddModule("__main__")))); 
    object pynamespace = pymodule.attr("__dict__"); 

    try { 
     // Initialize the embedded interpreter 
     object result = exec( "import code\n" 
           "__myInterpreter = code.InteractiveConsole() \n", 
           pynamespace); 
     // Run the code 
     str pyCode(codeToRun.c_str()); 
     pynamespace["__myCommand"] = pyCode; 
     result = eval("__myInterpreter.push(__myCommand)", pynamespace); 
    } catch(error_already_set) { 
     throw std::runtime_error(GetPythonError().c_str()); 
    } 
} 
+0

Vì vậy, về cơ bản, tôi nên khởi tạo một trình thông dịch Python của mình và sử dụng trình thông dịch này để khởi chạy trình thông dịch phụ, tất cả đều có không gian tên riêng của chúng? Trông giống như một giải pháp khả thi, nếu các thông dịch viên phụ không bị cảnh báo tương tự như những lời được thực hiện với Py_NewInterpreter. Tôi sẽ xem xét chi tiết và thử nghiệm nó. Cảm ơn! – nab

+0

Bạn đã hiểu. Lập trình một InteractiveInterpreter cung cấp cho bạn một môi trường mới mỗi lần. Tôi không chắc chắn những gì các quy tắc liên quan đến những gì được thừa kế từ thông dịch viên phụ huynh, nhưng điều đó phải dễ dàng để kiểm soát một trong hai cách. –

+0

Dường như làm những gì tôi muốn. Lưu ý rằng nó có cùng một thiếu sót cho các mô-đun khởi tạo (chúng chỉ được khởi tạo một lần). Nhưng nó hoạt động tốt để làm sạch không gian tên. Cảm ơn! – nab

0

Tôi muốn viết một kịch bản shell thực hiện chuỗi các kịch bản thử nghiệm với trường hợp mới của python mỗi lần. Hoặc viết nó trong python như

# run your tests in the process first 
# now run the user scripts, each in new process to have virgin env 
for script in userScript: 
    subprocess.call(['python',script])