从 JavaScript 代码调用 Python 函数

我想从 JavaScript 代码中调用一个 Python 函数,因为在 JavaScript 中没有替代方法可以做我想做的事情。这可能吗?您可以调整下面的代码片段来工作吗?

JavaScript 代码:

var tag = document.getElementsByTagName("p")[0];
text = tag.innerHTML;
// Here I would like to call the Python interpreter with Python function
arrOfStrings = openSomehowPythonInterpreter("~/pythoncode.py", "processParagraph(text)");

~/pythoncode.py包含使用高级库的函数,这些函数在 JavaScript 中不易编写:

import nltk # is not in JavaScript
def processParagraph(text):
...
nltk calls
...
return lst # returns a list of strings (will be converted to JavaScript array)
318241 次浏览

From the document.getElementsByTagName I guess you are running the javascript in a browser.

The traditional way to expose functionality to javascript running in the browser is calling a remote URL using AJAX. The X in AJAX is for XML, but nowadays everybody uses JSON instead of XML.

For example, using jQuery you can do something like:

$.getJSON('http://example.com/your/webservice?param1=x&param2=y',
function(data, textStatus, jqXHR) {
alert(data);
}
)

You will need to implement a python webservice on the server side. For simple webservices I like to use Flask.

A typical implementation looks like:

@app.route("/your/webservice")
def my_webservice():
return jsonify(result=some_function(**request.args))

You can run IronPython (kind of Python.Net) in the browser with silverlight, but I don't know if NLTK is available for IronPython.

Typically you would accomplish this using an ajax request that looks like

var xhr = new XMLHttpRequest();
xhr.open("GET", "pythoncode.py?text=" + text, true);
xhr.responseType = "JSON";
xhr.onload = function(e) {
var arrOfStrings = JSON.parse(xhr.response);
}
xhr.send();

All you need is to make an ajax request to your pythoncode. You can do this with jquery http://api.jquery.com/jQuery.ajax/, or use just javascript

$.ajax({
type: "POST",
url: "~/pythoncode.py",
data: { param: text}
}).done(function( o ) {
// do something
});

You cannot run .py files from JavaScript without the Python program like you cannot open .txt files without a text editor. But the whole thing becomes a breath with a help of a Web API Server (IIS in the example below).

  1. Install python and create a sample file test.py

    import sys
    # print sys.argv[0] prints test.py
    # print sys.argv[1] prints your_var_1
    
    
    def hello():
    print "Hi" + " " + sys.argv[1]
    
    
    if __name__ == "__main__":
    hello()
    
  2. Create a method in your Web API Server

    [HttpGet]
    public string SayHi(string id)
    {
    string fileName = HostingEnvironment.MapPath("~/Pyphon") + "\\" + "test.py";
    
    
    Process p = new Process();
    p.StartInfo = new ProcessStartInfo(@"C:\Python27\python.exe", fileName + " " + id)
    {
    RedirectStandardOutput = true,
    UseShellExecute = false,
    CreateNoWindow = true
    };
    p.Start();
    
    
    return p.StandardOutput.ReadToEnd();
    }
    
  3. And now for your JavaScript:

    function processSayingHi() {
    var your_param = 'abc';
    $.ajax({
    url: '/api/your_controller_name/SayHi/' + your_param,
    type: 'GET',
    success: function (response) {
    console.log(response);
    },
    error: function (error) {
    console.log(error);
    }
    });
    }
    

Remember that your .py file won't run on your user's computer, but instead on the server.

Communicating through processes

Example:

Python: This python code block should return random temperatures.

# sensor.py


import random, time
while True:
time.sleep(random.random() * 5)  # wait 0 to 5 seconds
temperature = (random.random() * 20) - 5  # -5 to 15
print(temperature, flush=True, end='')

Javascript (Nodejs): Here we will need to spawn a new child process to run our python code and then get the printed output.

// temperature-listener.js


const { spawn } = require('child_process');
const temperatures = []; // Store readings


const sensor = spawn('python', ['sensor.py']);
sensor.stdout.on('data', function(data) {


// convert Buffer object to Float
temperatures.push(parseFloat(data));
console.log(temperatures);
});

Despite what some replies and comments suggest, there are a number of ways for using Python on the front-end. For your question in particular, see this reply.