Search code examples
pythonpyinstaller

How to convert py script with input parameters to exe, and call the exe in another py script


I'm new to Python. In order to run the py script1 referenced some third-part libraries in a system without these libraties, I tried to convert the py to exe by pyinstaller, and call the exe in another py script2, the codes are probably look like this:

script1:

def func(x):
    c = sum(x)
    print(c)

I ran

pyinstaller -F -w script1.py  -->script1.exe

script2:

impose subprocess
x = [1,2,3]
subprocess.run([r"...\script1.exe",x])

The codes above failed to work. I guess the problem is in the parameters transfer, I found the sys.argv[] transfer method, but it seems can't solve my problem either.


Solution

  • If you want to run .exe with parameters then you have to

    • use sys.argv to get parameters but you have to skip first element which is name of your program - sys.argv[1:]
    • convert all values to int() because it can send values only as string
    • run your function with parameters `func(values)
    import sys
    
    def func(x):
        c = sum(x)
        print(c)
        
    if __name__ == '__main__':    
        values = []
        
        for item in sys.argv[1:]:
            values.append( int(item) )
            
        func(values)    
    

    Before you convert to .exe you should test your code

    python.exe script1.py 1 2 3 
    

    And when you execute it then you have to use flat list with strings (because it can send only strings)

    run( [r"...\script1.exe", '1', '2', '3'] )
    

    but you have nested list, and this list has integer values

    run( [r"...\script1.exe", [1, 2, 3] ] )
    

    So you need something like this

    import subprocess
    
    x = [1, 2, 3]
    
    items = []
    
    for value in x:
        items.append( str(value) )
    
    # add two lists to create one flat list
    subprocess.run( [r"...\script1.exe"] + items )  
    

    You can reduce code using list comprehension or map()

    import sys
    
    def func(x):
        c = sum(x)
        print(c)
    
    if __name__ == '__main__':    
        values = [int(item) for item in sys.argv[1:] ]
        #values = list(map(int, sys.argv[1:]))
            
        func(values)    
    

    and

    import subprocess
    
    x = [1, 2, 3]
    
    items = [str(value) for value in x]
    #items = list(map(str, x))
    
    subprocess.run( [r"...\script1.exe"] + items )
    

    EDIT:

    func() has to use print() to send result back to first script.

    And first script has to capture output (stdout)

    process = subprocess.run( [r"...\script1.exe"] + items, capture_output=True)
    
    text = process.stdout.decode()
    result = int( text )
    
    print(result)