Виклик функції Python із коду JavaScript


85

Я хотів би викликати функцію Python із коду JavaScript, оскільки в 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. Ви захочете запустити це на сервері.
Fred Foo

Javascript працює на клієнті. Я припускаю, що python працює на сервері. Ви можете надіслати запит ajax на сервер. Це не буде швидко.
Джон Дворжак,

1
Використовуючи ajax, надсилайте текст до сценарію python на своєму сервері. Налаштуйте сценарій для повернення даних у зручному для синтаксичного аналізу (для js) нотації (наприклад, JSON) і призначте результат arrOfStrings в обробнику успіху.
Асад Саедуддін,

5
Ви можете запустити офіційний інтерпретатор Python у браузері, скомпілювавши його за допомогою clang та Emscripten . Це робилося і раніше.

1
@FredFoo, Що насправді було б щасливим, якби браузери не запускали ECMAScript (який називається JavaScript із досить сумнівних історичних причин.) Що також було б щасливим, якби браузери запускали захищений підмножини (що кожен має на увазі під запуском що-небудь у браузері, незважаючи на вашу солом'яну людину) Python з 90-х років, тому нам не доведеться мати справу з поточним веб-безладом.
jdk1.0

Відповіді:


58

Все, що вам потрібно, - це зробити запит ajax до вашого pythoncode. Ви можете зробити це за допомогою 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

2
Я запускаю цей код у firebug, але він реєструється[]
xralf

2
Добре, то як це правильно? Мій файл Python містить правильну функцію. Чи слід викликати функцію в Python, і аргументом буде sys.argv [1]?
xralf

7
Дякуємо за відповідь, але для того, щоб скрипт python виконав його, його слід розгорнути веб-сервером, який підтримує його через CGI або WSGI. Не могли б ви включити у свою відповідь, як вирішити цю проблему?
Маттео,

2
О, я був би дуже радий відредагувати вашу відповідь, якби я знав, як це зробити, я сподівався, що ви можете надати якусь пораду, бо я отримую цю помилку, XMLHttpRequest cannot load file:~/pythoncode.py. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resourceі хоча я розумів, у чому проблема, не знаю, як це зробити виріши це. Будь-який корисний вказівник? Дуже дякую. (до речі ... chessheaven здається справді чудовим! Я спробую це точно, добре, що ти поставив милу дівчинку у своєму профілі;))
Маттео

26

З document.getElementsByTagNameя думаю, ви запускаєте javascript у браузері.

Традиційним способом представити функціональність javascript, який працює в браузері, є виклик віддаленої URL-адреси за допомогою AJAX. X в AJAX призначений для XML, але сьогодні всі використовують JSON замість XML.

Наприклад, використовуючи jQuery, ви можете зробити щось на зразок:

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

Вам потрібно буде реалізувати веб-службу python на стороні сервера. Для простих веб-сервісів я люблю використовувати Flask .

Типова реалізація виглядає так:

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

Ви можете запустити IronPython (різновид Python.Net) у браузері за допомогою silverlight , але я не знаю, чи доступна 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

Ви не можете запускати .py-файли з JavaScript без програми Python, як не можна відкривати .txt-файли без текстового редактора. Але все це стає диханням за допомогою сервера веб-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. Створіть метод на своєму веб-сервері 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);
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.