> 文档中心 > 所有编程语言调用python方式,非命令行可以获取返回值,适合所有Python版本

所有编程语言调用python方式,非命令行可以获取返回值,适合所有Python版本


目前为止,如java,go等编程语言调用python的主要方式是命令行调用或者利用python c api,jpython等方式进行调用,这些方式各有各自的缺陷,比如jpython只能试用特定python,命令行无法获得返回值等,为此我想到一个方法,及python调用python,暴露一个api,可以适合各种编程语言,切对于Python所以import都适用,直接先上代码了

from flask import request, jsonify, Flaskimport importlibimport inspectimport sysimport jsonapp = Flask(__name__)@app.route('/', methods=["POST"])def run_py():  # put application's code here    data_list = []    data = json.loads(request.get_data(as_text=True))    method = data["method"]    path = data["path"]    type = data["type"]    args = data["args"]    sys_path = data["sys"]    for p in sys_path: sys.path.append(p)   #moudle_name无实际作用    spec = importlib.util.spec_from_file_location("moudle_name", path)    odm = importlib.util.module_from_spec(spec)    spec.loader.exec_module(odm)    v_list = []    if hasattr(odm, method): func = getattr(odm, method) v_list = [] r = inspect.getfullargspec(func)  # 获取FullArgSpec对象 j = 0 for i in r.args:     if type == "map":  v_list.append(args[i])     elif type == "array":  v_list.append(args[j])  j = j + 1 res = func(*v_list) return jsonify({"code": 200, "msg": "ok", "data": res})if __name__ == '__main__':    app.run(host="127.0.0.1",port=5000)

该段代码有5个参数

  • method:方法名字
  • path:py文件路径
  • args:python方法参数
  • type:参数类型,支持map和array
  • sys:依赖库地址,在Python使用虚拟环境时可以使用

接下来使用python写个简单demoo

import requestsimport jsondef add(a,b):a = 1b = 2return a+b,a,bdef test():url = "https://www.baidu.com"response = requests.request("GET", url)data=json.dumps({"test":"该方法只是为了测试有依赖情况下是否可以使用"})return data

该py文件地址在/home/lihang/PycharmProjects/test/test.py

我们先使用postman测试一下
在这里插入图片描述
在这里插入图片描述
很明显成功了,接着使用各种编程语言尝试

Java

OkHttpClient client = new OkHttpClient().newBuilder()  .build();MediaType mediaType = MediaType.parse("application/json");RequestBody body = RequestBody.create(mediaType, "{\n    \"method\":\"test\",\n    \"type\":\"map\",\n    \"path\":\"/home/lihang/PycharmProjects/test/test.py\",\n    \"args\":{\n    },\n    \"sys\":[]\n}");Request request = new Request.Builder()  .url("http://127.0.0.1:5000/")  .method("POST", body)  .addHeader("Content-Type", "application/json")  .build();Response response = client.newCall(request).execute();

Go

package mainimport (  "fmt"  "strings"  "net/http"  "io/ioutil")func main() {  url := "http://127.0.0.1:5000/"  method := "POST"  payload := strings.NewReader(`{    "method":"test",    "type":"map",    "path":"/home/lihang/PycharmProjects/test/test.py",    "args":{    },    "sys":[]}`)  client := &http.Client {  }  req, err := http.NewRequest(method, url, payload)  if err != nil {    fmt.Println(err)    return  }  req.Header.Add("Content-Type", "application/json")  res, err := client.Do(req)  if err != nil {    fmt.Println(err)    return  }  defer res.Body.Close()  body, err := ioutil.ReadAll(res.Body)  if err != nil {    fmt.Println(err)    return  }  fmt.Println(string(body))}

bash

curl --location --request POST 'http://127.0.0.1:5000/' \--header 'Content-Type: application/json' \--data-raw '{    "method":"test",    "type":"map",    "path":"/home/lihang/PycharmProjects/test/test.py",    "args":{    },    "sys":[]}'

Ruby

require "uri"require "json"require "net/http"url = URI("http://127.0.0.1:5000/")http = Net::HTTP.new(url.host, url.port);request = Net::HTTP::Post.new(url)request["Content-Type"] = "application/json"request.body = JSON.dump({  "method": "test",  "type": "map",  "path": "/home/lihang/PycharmProjects/test/test.py",  "args": {},  "sys": []})response = http.request(request)puts response.read_body