簡體   English   中英

Python - 如何將單獨的模塊(不運行)作為單獨的進程運行?

[英]Python - how can I run separate module (not function) as a separate process?

tl,dr:我如何以可編程的方式執行 python 模塊(不起作用)作為與不同 python 模塊的單獨進程?

在我的開發筆記本電腦上,我有一個包含瓶子服務器的“服務器”模塊。 在這個模塊中,name==main 子句啟動了 Bottle 服務器。

@bt_app.post("/")
def server_post():
    << Generate response to 'http://server.com/' >>

if __name__ == '__main__':
    serve(bt_app, port=localhost:8080)

我還有一個包含 pytests 的“test_server”模塊。 在此模塊中,name==main 子句運行 pytest 並顯示結果。

def test_something():
        _rtn = some_server_function()
        assert _rtn == desired

if __name__ == '__main__':
    _rtn = pytest.main([__file__])
    print("Pytest returned: ", _rtn)

目前,我手動運行服務器模塊(在 localhost 上啟動 web 服務器),然后手動啟動 pytest 模塊,該模塊發出 html 模塊請求並檢查對正在運行的服務器的響應。

有時我忘記啟動服務器模塊。 沒什么大不了的,但很煩人。 所以我想知道我是否可以以編程方式將服務器模塊作為與 pytest 模塊分開的進程啟動(就像我現在手動做的那樣),所以我不會忘記手動啟動它。

謝謝

有我的測試用例目錄樹:

test
├── server.py
└── test_server.py

server.py使用 flask 啟動 web 服務器。

from flask import Flask                                                                                                                                                
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'


if __name__ == '__main__':
    app.run()

test_server.py發出測試請求。

import sys                                                                                                                                                             
import requests
import subprocess
import time

p = None  # server process

def start_server():
    global p
    sys.path.append('/tmp/test')
    # here you may want to do some check. 
    # whether the server is already started, then pass this fucntion
    kwargs = {}  # here u can pass other args needed
    p = subprocess.Popen(['python','server.py'], **kwargs)

def test_function():
    response = requests.get('http://localhost:5000/')
    print('This is response body: ', response.text)

if __name__ == '__main__':
    start_server()
    time.sleep(3)  # waiting server started
    test_function()
    p.kill()

然后你可以做python test_server來啟動服務器並做測試用例。

PS:Popen Popen()需要 python3.5+。 如果版本較舊,請改用run

import logging
import threading
import time

def thread_function(name):
    logging.info("Thread %s: starting", name)
    time.sleep(2)
    logging.info("Thread %s: finishing", name)

if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO,
                        datefmt="%H:%M:%S")

    threads = list()
    for index in range(3):
        logging.info("Main    : create and start thread %d.", index)
        x = threading.Thread(target=thread_function, args=(index,))
        threads.append(x)
        x.start()

    for index, thread in enumerate(threads):
        logging.info("Main    : before joining thread %d.", index)
        thread.join()
        logging.info("Main    : thread %d done", index)

使用線程,您可以一次運行多個進程!

Wim基本上回答了這個問題。 我查看了子流程模塊。 在閱讀它時,我偶然發現了 os.system function。

簡而言之,子進程是一個用於運行程序的高度靈活和功能強大的程序。 另一方面,os.system 要簡單得多,功能要少得多。

只運行一個 python 模塊很簡單,所以我選擇了 os.system。

import os
server_path = "python -m ../src/server.py"
os.system(server_path)

維姆,謝謝你的指點。 如果這是一個完整的答案,我會贊成的。 重做一個完整的答案,我會這樣做。

異步救援。

import gevent
from gevent import monkey, spawn
monkey.patch_all()
from gevent.pywsgi import WSGIServer

@bt_app.post("/")
def server_post():
    << Generate response to 'http://server.com/' >>

def test_something():
    _rtn = some_server_function()
    assert _rtn == desired
    print("Pytest returned: ",_rtn)
    sleep(0)

if __name__ == '__main__':
    spawn(test_something) #runs async
    server = WSGIServer(("0.0.0.0", 8080, bt_app)
    server.serve_forever()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM