从JavaScript代码调用Python函数


85

我想从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)

8
不,浏览器(幸运的是)不会执行任意的Python代码。您将要在服务器上运行它。
弗雷德·富

Javascript在客户端上运行。我假设python在服务器上运行。您可以将ajax请求发送到服务器。不会很快。
约翰·德沃夏克

1
使用ajax,将文本发送到服务器上的python脚本。设置脚本以易于解析(对于js)表示法(如JSON)返回数据,并将结果分配给成功处理程序中的arrOfStrings。
Asad Saeeduddin

5
您可以使用clang和Emscripten对其进行编译,从而在浏览器中运行官方的Python解释器。之前已经做过。

1
@FredFoo,实际上幸运的是,如果浏览器运行ECMAScript(出于相当可疑的历史原因,它被称为JavaScript。)也很幸运的是,如果浏览器运行的是安全子集(任何人通过运行它的含义)自从90年代以来,就一直没有使用Python的浏览器中的任何内容,尽管您是个草率的人,所以我们不必处理当前的网络混乱。
jdk1.0

Answers:


58

您需要做的就是向您的pythoncode发出ajax请求。您可以使用jquery http://api.jquery.com/jQuery.ajax/进行此操作,也可以仅使用javascript

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

1
看起来很有趣。processParagraph(text)使返回值以变量结尾的调用在哪里arrOfStrings
xralf 2012年

2
我正在Firebug中运行代码,但它会记录[]
xralf 2012年

2
好,那怎么了?我的Python文件包含正确的函数。我应该在Python中调用该函数,并且参数为sys.argv [1]吗?
xralf 2012年

7
感谢您的回答,但为了使python脚本执行,必须由通过CGI或WSGI支持该脚本的Web服务器部署。您能否在答案中包括如何解决该问题?
Matteo

2
哦,如果我知道该怎么做,我会很乐意编辑您的答案,希望您能提供一些建议,因为我遇到了这个错误XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource,即使我知道问题所在也不知道如何解决。解决这个问题。任何有用的指针?非常感谢。(btw ... chessheaven看起来真的很棒!我会尝试的,好东西,您在个人资料图片中放了一个可爱的女孩;))
Matteo 2014年

26

来自 document.getElementsByTagName我想您正在浏览器中运行javascript。

向浏览器中运行的javascript公开功能的传统方式是使用AJAX调用远程URL。AJAX中的X用于XML,但如今每个人都使用JSON而不是XML。

例如,使用jQuery,您可以执行以下操作:

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

您将需要在服务器端实现python网络服务。对于简单的Web服务,我喜欢使用Flask

典型的实现如下所示:

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

您可以使用silverlight在浏览器中运行IronPython(Python.Net类),但是我不知道NLTK是否可用于IronPython。


9

通常,您可以使用如下所示的ajax请求来完成此操作

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();

4

如果没有Python程序,就无法从JavaScript运行.py文件,就像没有文本编辑器就无法打开.txt文件一样。但是,借助Web API服务器(在下面的示例中为IIS),整个过程变得令人屏息。

  1. 安装python并创建示例文件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. 在Web API服务器中创建方法

    [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. 现在使用您的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);
           }
        });
    }
    

请记住,您的.py文件不会在用户的计算机上运行,​​而是在服务器上运行。


1

通过流程进行沟通

例:

Python:此python代码块应返回随机温度。

# 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):在这里,我们将需要产生一个新的子进程来运行我们的python代码,然后获取打印的输出。

// 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);
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.