2013-06-01 3 views
3

Я нахожусь в linux, и у меня есть один скрипт python, который я хочу вызвать из другого скрипта python. Я не хочу импортировать его в качестве модуля (для уровня безопасности, а теперь для академического упражнения, потому что я хочу понять это), я хочу, чтобы на самом деле один сценарий вызывал другого с помощью os.system() или другая функция, подобная этой, и чтобы другой скрипт вернул список кортежей в первый скрипт.Получение обратной передачи из другого скрипта python

Любые идеи? Я знаю, что это может быть не оптимальный способ сделать это, но я бы хотел попробовать и изучить некоторые вещи в этом процессе.

ответ

3

Импорт модуля отличается от его выполнения в качестве сценария. Если вы не доверяете дочернему скрипту Python; вы не должны запускать из него какой-либо код.

регулярный способ использовать код из другого модуля Python:

import another_module 

result = another_module.some_function(args) 

Если вы хотите, чтобы выполнить его вместо импорта:

namespace = {'args': [1,2,3]} # define __name__, __file__ if necessary 
execfile('some_script.py', namespace) 
result = namespace['result'] 

execfile() используется очень редко в Python. Это может быть полезно в отладчике, профилировщике или для запуска setup.py в таких инструментах, как pip, easy_install.

См. Также runpy module.

Если другой скрипт выполнен в другом процессе; вы можете использовать много IPC methods. Самый простой способ, это просто труба сериализовать (объекты Python, преобразованные в виде массива байт) ввод арг Into подпроцесса STDIN и прочитать результат обратно из ее стандартного вывода, как suggested by @kirelagin:

import json 
import sys 
from subprocess import Popen, PIPE 

marshal, unmarshal = json.dumps, json.loads 

p = Popen([sys.executable, 'some_script.py'], stdin=PIPE, stdout=PIPE) 
result = unmarshal(p.communicate(marshal(args))[0]) 

где some_script.py может быть:

#!/usr/bin/env python 
import json 
import sys 

args = json.load(sys.stdin) # read input data from stdin 
result = [x*x for x in args] # compute result 
json.dump(result, sys.stdout) # write result to stdout 
+0

Спасибо! Я закончил его, но потому, что размер данных был приемлемо малым и легким для моделирования в виде строки, мне не нужно было сериализовать его. – Nathan

3

Вы можете использовать subprocess:

subprocess.call(["python", "myscript.py"]) 

Это также возвращает значение возврата процесса (например, 0 или 1).

2

Для возврата списка вам понадобится сериализация. Я бы предложил pickle или JSON.

Ваш другой скрипт напечатает его до stdout, и вызывающий скрипт будет читать его и десериализовать.

+0

Так что, в основном, данные преобразуются в большой int, возвращают этот код, а затем меняют его? Как долго может возвращаться системный код? – Nathan

+0

@Nathan No-no, превратите его в строку и напишите в 'stdout'. Затем ваш вызывающий скрипт будет читать его через канал (проверьте документацию подпроцесса.Popen). – kirelagin

+0

Безопасно ли это? Неужели кто-то сможет быть перехвачен? Не могли бы вы привести мне пример этого? Скажем, у меня есть a.py и b.py, как бы я пошел по этому процессу? – Nathan

1

Знаете, ZMQ очень полезен для межпроцессного общения. Вы можете использовать его с объектами json.

Вот python binding

0

Это очень просто.

import popen2 
fout, fin = popen2.popen2('python your_python_script.py') 
data = fout.readline().strip() 
if data <> '': 
    # you have your `data`, so do something with it 
+0

Да, и не забывайте 'из __future__ import barry_as_FLUFL';). – kirelagin

Смежные вопросы