Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute python code without invoking import statement each time

Here is a sample python script. How do I run this script multiple times from command line so that the import line is not called every time? The import statement takes too long to load.

import arcpy
val = arcpy.GetCellValue_management("D:\dem-merged\lidar_wsg84", "-95.090174910630012 29.973962146120652", "")
print str(val)
like image 941
Shaunak Avatar asked Dec 27 '22 17:12

Shaunak


2 Answers

This problem has no solution if you strictly want this script "to be called from another program. by issuing 'python script.py' on command line". If you want to do the "heavy import" only once, you have to start python script only once. Think about starting a daemon, which will start once and then process calls from other program. This way all initialization has to be done only one time and next calls will be fast. And if you split your python code into two parts (first part for daemon, second for daemon client), you'll be able to call 'python client.py' from another program, but actual computation will be performed by daemon, which is started just one time.

As example:

daemon.py

import socket
#import arcpy

def actual_work():
    #val = arcpy.GetCellValue_management("D:\dem-merged\lidar_wsg84", "-95.090174910630012 29.973962146120652", "")
    #return str(val)
    return 'dummy_reply'


def main():
    sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
    try:
        sock.bind( ('127.0.0.1', 6666) )

        while True:
            data, addr = sock.recvfrom( 4096 )
            reply = actual_work()
            sock.sendto(reply, addr)
    except KeyboardInterrupt:
        pass
    finally:
        sock.close()


if __name__ == '__main__':
    main()

client.py

import socket
import sys


def main():
    sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
    sock.settimeout(1)
    try:
        sock.sendto('', ('127.0.0.1', 6666))
        reply, _ = sock.recvfrom(4096)
        print reply
    except socket.timeout:
        sys.exit(1)
    finally:
        sock.close()


if __name__ == '__main__':
    main()
like image 88
Alex Laskin Avatar answered Jan 13 '23 13:01

Alex Laskin


It's virtually impossible. Once you leave the interpreter, the modules that were imported are no longer in the memory. It's similar to asking Firefox to save large webpages in memory because the read rate to the cache takes too long. Once Firefox (or Python) is shut off, it's pretty much bye-bye anything in the RAM.

You can make the load time faster, but at your own risk. By running

python -O 

you can make it go a bit faster. You can also add another 'O' to make it go just a bit faster. However, this can make some programs buggy and doesn't always work.

You could copy the functions you need into your program by doing

from arcpy import <what you need>

and that might make things go slightly faster.

like image 23
Mithrandir Avatar answered Jan 13 '23 13:01

Mithrandir