Gọi hàm Python từ mã JavaScript


85

Tôi muốn gọi một hàm Python từ mã JavaScript, vì không có giải pháp thay thế nào trong JavaScript để làm những gì tôi muốn. Điều này có khả thi không? Bạn có thể điều chỉnh đoạn mã dưới đây để hoạt động không?

Mã 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 chứa các hàm sử dụng thư viện nâng cao không dễ viết tương đương trong 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
Không, các trình duyệt (may mắn thay) sẽ không thực thi mã Python tùy ý. Bạn sẽ muốn chạy nó trong một máy chủ.
Fred Foo

Javascript chạy trên máy khách. Tôi giả sử python chạy trên máy chủ. Bạn có thể gửi một yêu cầu ajax đến máy chủ. Sẽ không nhanh đâu.
John Dvorak

1
Sử dụng ajax, gửi văn bản tới một tập lệnh python trên máy chủ của bạn. Thiết lập tập lệnh để trả về dữ liệu dưới dạng ký hiệu dễ phân tích cú pháp (đối với js) (như JSON) và gán kết quả cho arrOfStrings trong trình xử lý thành công.
Asad Saeeduddin

5
Bạn có thể chạy trình thông dịch Python chính thức trong trình duyệt bằng cách biên dịch nó bằng clangEmscripten . Việc này đã được làm từ trước.

1
@FredFoo, Điều thực sự may mắn là nếu các trình duyệt không chạy ECMAScript (được gọi là JavaScript vì những lý do lịch sử khá khó hiểu.) Điều may mắn nữa là nếu các trình duyệt đang chạy một tập hợp con an toàn (đó là ý nghĩa của bất kỳ ai khi chạy bất cứ thứ gì trong trình duyệt, mặc dù là người đàn ông rơm của bạn) của Python từ những năm 90, vì vậy chúng tôi sẽ không phải đối phó với mớ hỗn độn web hiện tại.
jdk1.0

Câu trả lời:


58

Tất cả những gì bạn cần là thực hiện một yêu cầu ajax tới pythoncode của bạn. Bạn có thể thực hiện việc này với jquery http://api.jquery.com/jQuery.ajax/ hoặc chỉ sử dụng javascript

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

1
Trông nó thật thú vị. Đâu có thể là lời gọi của processParagraph(text)để các giá trị trả về kết thúc trong biến arrOfStrings?
xralf

2
Tôi đang chạy mã này trong firebug, nhưng nó ghi nhật ký[]
xralf

2
OK, vậy làm thế nào là đúng? Tệp Python của tôi chứa hàm đúng. Tôi có nên gọi hàm bằng Python và đối số sẽ là sys.argv [1] không?
xralf

7
Cảm ơn câu trả lời, nhưng để tập lệnh python thực thi nó phải được triển khai bởi máy chủ web hỗ trợ nó qua CGI hoặc WSGI. Bạn có thể vui lòng đưa vào câu trả lời của bạn cách giải quyết vấn đề đó không?
Matteo

2
Ồ, tôi rất vui khi chỉnh sửa câu trả lời của bạn nếu tôi biết cách làm điều đó, tôi hy vọng bạn có thể cung cấp một số lời khuyên, vì tôi đang gặp lỗi này XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourcevà mặc dù tôi hiểu vấn đề là gì nhưng tôi không biết làm thế nào để giải quyết nó. Bất kỳ con trỏ hữu ích? Cảm ơn rất nhiều. (! btw ... chessheaven dường như thực sự tuyệt vời tôi sẽ thử nó ra cho chắc chắn, điều tốt bạn đặt một cô gái dễ thương trong ảnh hồ sơ của bạn;))
Matteo

26

Từ document.getElementsByTagNameTôi đoán bạn đang chạy javascript trong trình duyệt.

Cách truyền thống để hiển thị chức năng cho javascript đang chạy trong trình duyệt là gọi một URL từ xa bằng AJAX. X trong AJAX dành cho XML, nhưng ngày nay mọi người đều sử dụng JSON thay vì XML.

Ví dụ, bằng cách sử dụng jQuery, bạn có thể thực hiện một số việc như:

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

Bạn sẽ cần triển khai một dịch vụ web python ở phía máy chủ. Đối với các dịch vụ web đơn giản, tôi thích sử dụng Flask .

Một cách triển khai điển hình giống như sau:

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

Bạn có thể chạy IronPython (loại Python.Net) trong trình duyệt với silverlight , nhưng tôi không biết liệu NLTK có khả dụng cho IronPython hay không.


9

Thông thường, bạn sẽ thực hiện điều này bằng cách sử dụng một yêu cầu ajax trông giống như

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

Bạn không thể chạy tệp .py từ JavaScript mà không có chương trình Python giống như bạn không thể mở tệp .txt mà không có trình soạn thảo văn bản. Nhưng toàn bộ mọi thứ sẽ trở thành hơi thở với sự trợ giúp của Máy chủ API Web (IIS trong ví dụ bên dưới).

  1. Cài đặt python và tạo tệp mẫu 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. Tạo một phương thức trong Máy chủ API Web của bạn

    [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. Và bây giờ cho JavaScript của bạn:

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

Hãy nhớ rằng tệp .py của bạn sẽ không chạy trên máy tính của người dùng mà thay vào đó trên máy chủ.


1

Giao tiếp thông qua các quy trình

Thí dụ:

Python: Khối mã python này sẽ trả về nhiệt độ ngẫu nhiên.

# 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): Ở đây chúng ta sẽ cần tạo ra một tiến trình con mới để chạy mã python của chúng ta và sau đó lấy đầu ra được in.

// 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);
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.