เรียกใช้ฟังก์ชัน Python จากโค้ด JavaScript


87

ฉันต้องการเรียกใช้ฟังก์ชัน 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)

9
ไม่เบราว์เซอร์ (โชคดี) จะไม่เรียกใช้รหัส Python โดยพลการ คุณจะต้องเรียกใช้สิ่งนั้นในเซิร์ฟเวอร์
Fred Foo

Javascript ทำงานบนไคลเอนต์ ฉันถือว่า python ทำงานบนเซิร์ฟเวอร์ คุณสามารถส่งคำขอ ajax ไปยังเซิร์ฟเวอร์ มันจะไม่เร็ว
John Dvorak

1
ใช้ ajax ส่งข้อความไปยังสคริปต์ python บนเซิร์ฟเวอร์ของคุณ ตั้งค่าสคริปต์เพื่อส่งคืนข้อมูลในรูปแบบง่ายต่อการแยกวิเคราะห์ (สำหรับ js) (เช่น JSON) และกำหนดผลลัพธ์ให้กับ arrOfStrings ในตัวจัดการความสำเร็จ
Asad Saeeduddin

5
คุณสามารถเรียกใช้ล่ามงูใหญ่อย่างเป็นทางการในเบราว์เซอร์โดยการรวบรวมโดยใช้เสียงดังกราวและ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 โปรดระบุคำตอบของคุณเกี่ยวกับวิธีแก้ปัญหานั้นได้ไหม
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

26

จาก document.getElementsByTagNameฉันเดาว่าคุณกำลังเรียกใช้จาวาสคริปต์ในเบราว์เซอร์

วิธีดั้งเดิมในการแสดงฟังก์ชันการทำงานของจาวาสคริปต์ที่ทำงานในเบราว์เซอร์คือการเรียก 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 webservice ที่ฝั่งเซิร์ฟเวอร์ สำหรับ webservices ง่ายผมชอบที่จะใช้ขวด

การใช้งานทั่วไปมีลักษณะดังนี้:

@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 ได้หากไม่มีโปรแกรมแก้ไขข้อความ แต่สิ่งทั้งหมดจะกลายเป็นลมหายใจด้วยความช่วยเหลือของ Web API Server (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 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. และตอนนี้สำหรับ 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 ของคุณจะไม่ทำงานบนคอมพิวเตอร์ของผู้ใช้ของคุณ แต่จะอยู่บนเซิร์ฟเวอร์แทน


2

การสื่อสารผ่านกระบวนการ

ตัวอย่าง:

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);
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.