简体   繁体   中英

Pass function and arguments from node to python, using child_process

I am new to child_process and I want to experiment with its capabilities.

Is there any way to pass a function and arguments to a python file, using spawn (or exec or execFile is spawn cannot do it)?

I want to do something like (pseudocode)

spawnORexecORexefile (python path/to/python/file function [argument1, argument2] ) 

or maybe

spawnORexecORexefile (python path/to/python/file function(argument1, argument2) ) 

Please explain and maybe give an example, because I am a newbie

How I am doing it now?

in node

 var process = spawn('python', [path/to/pythonFile.py, 50, 60] );  

in pythonFile.py

import sys 
import awesomeFile

hoodie = int(sys.argv[1])
shoe = int(sys.argv[2])

awesomeFile.doYourMagic().anotherThing(hoodie, shoe)

as you can see, from node, I send data to pythonFile and then to awesomeFile , to a specific function

I would like to "cut the middle man" and remove the pythonFile and send data from node directly to the awesomeFile file, to a specific function. This is why I am asking

Thanks

You can run a specific Python function from the command-line using the form python -c 'import foo; print foo.hello()' python -c 'import foo; print foo.hello()' (from https://stackoverflow.com/a/3987113/5666087 ).

Place both the files below in the same directory, and run with node index.js . You should see the following output:

Hoodie: 10
Shoe: 15

awesomeFile.py

def myfunc(hoodie, shoe):
    hoodie = int(hoodie)
    shoe = int(shoe)
    print("Hoodie:", hoodie)
    print("Shoe:", shoe)

index.js

const { spawn } = require('child_process');
let hoodie = 10,
    shoe = 15;
const result = spawn("python",
    ["-c", `import awesomeFile; awesomeFile.myfunc(${hoodie}, ${shoe})`])
result.stdout.pipe(process.stdout)

You can group all the relevant functions you want to call to class and make a dictionary out of a class that maps to the class function. You can directly call awesome.py without an intermediate index.py . You can extend the class AwesomeFile with your methods

The follow program will take user input -

  1. which python file to run
  2. which method to run
  3. method arguments
  4. Number of arguments mismatch
  5. What if unknown methods are given

awesomeFile.py

import sys

class AwesomeFile:

    def __init__(self):
        pass

    def doYourMagic(self):
        return self
    
    def anotherThing(self, hoodie, shoe):
        print(int(hoodie))
        print(int(shoe))

awesomeFile = AwesomeFile()
methods = {m:getattr(awesomeFile, m) for m in dir(AwesomeFile) if not m.startswith('__')}

def run():
    method_name = sys.argv[1]
    if method_name not in methods:
        print(f"Unknown Method {method_name}")
        return
    methodArgCount = methods[method_name].__code__.co_argcount
    if methodArgCount - 1 != len(sys.argv[2:]):
        print(f"Method {method_name} takes {methodArgCount - 1} arguments but you have given {len(sys.argv[2:])}")
        return
    
    methods[method_name](*sys.argv[2:])

if __name__ == "__main__":
    run()

index.js

Note** - You would to install prompt - npm i prompt

'use strict';
var prompt = require('prompt');
const { spawn } = require( 'child_process' );

var prompt_attributes = [
    {        
        name: 'pythonFilePath'
    },
    {   
        name: 'cmdLineArgs'
    }
];

prompt.start();

prompt.get(prompt_attributes, function (err, result) {
    if (err) {
        console.log(err);
        return 1;
    }else {
        console.log('Command-line received data:');
        var filePath = result.pythonFilePath;
        var cmdLineArgs = result.cmdLineArgs;
        var args = cmdLineArgs.split(" ");
        args.unshift(filePath);
        
        const pythonProgram = spawn( 'python' , args);

        pythonProgram.stdout.on( 'data', data => {
            console.log( `stdout:\n\n ${data}` );
        } );

        pythonProgram.stderr.on( 'data', data => {
            console.log( `stderr: ${data.data}` );
        } );

        pythonProgram.on( 'close', code => {
            console.log( `child process exited with code ${code}` );
        } );
    
    }
});

To run the program -

I/O :

Argument Mistmatch -

prompt: Python File Path. Give absolute or relative path: ../python_files/awesomeFile.py # python file can be any location in the system
prompt: Command Line Arguments. Format = func_name arguments_list (Ex addFunc 1 2):  anotherThing 1
Command-line received data:
stdout:

 Method anotherThing takes 2 arguments but you have given 1

child process exited with code 0

Function Not found

prompt: Python File Path. Give absolute or relative path:  ../python_files/awesomeFile.py
prompt: Command Line Arguments. Format = func_name arguments_list (Ex addFunc 1 2):  helloworld 1 2
Command-line received data:
stdout:

 Unknown Method helloworld

child process exited with code 0

Success Case:

prompt: Python File Path. Give absolute or relative path:  ../python_files/awesomeFile.py
prompt: Command Line Arguments. Format = func_name arguments_list (Ex addFunc 1 2):  anotherThing 50 60
Command-line received data:
stdout:

 50
60

child process exited with code 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM