每次执行python代码而不调用import语句

时间:2011-07-14 01:00:14

标签: python command-line import

这是一个示例python脚本。如何从命令行多次运行此脚本,以便每次都不调用导入行? import语句加载时间太长。

import arcpy
val = arcpy.GetCellValue_management("D:\dem-merged\lidar_wsg84", "-95.090174910630012 29.973962146120652", "")
print str(val)

7 个答案:

答案 0 :(得分:6)

如果您严格要求从另一个程序调用此脚本,请通过在命令行上发出'python script.py'来解决此问题。 如果你只想做一次“重导入”,你必须只启动一次python脚本。 考虑启动一个守护进程,它将启动一次,然后处理来自其他程序的调用。这样,所有初始化只需要进行一次,接下来的调用将很快。 如果你将你的python代码分成两部分(守护进程的第一部分,守护进程客户端的第二部分),你将能够从另一个程序调用'python client.py',但实际的计算将由守护进程执行,这是开始只有一次。

例如:

<强> 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()

答案 1 :(得分:2)

这几乎是不可能的。离开解释器后,导入的模块不再在内存中。这类似于要求Firefox在内存中保存大型网页,因为对缓存的读取速度需要太长时间。一旦Firefox(或Python)关闭,它几乎可以在RAM中再见。

您可以加快加载时间,但风险自负。通过运行

python -O 

你可以让它快一点。您还可以添加另一个“O”以使其更快一些。但是,这可能会使某些程序出错并且无法正常运行。

您可以通过

将所需的功能复制到程序中
from arcpy import <what you need>

这可能会让事情变得更快。

答案 2 :(得分:1)

据我所知,模块导入一次。所以如果你这样做:

import a
import a

它只导入一次。因此,不是多次运行脚本,也许你可以改变它来一次性制作所有副本。

如果您必须多次运行此特定脚本,我认为您无法避免导入,并且您每次都导入它。

答案 3 :(得分:1)

我能想到的一个解决方案是让一个持久运行的服务器进程执行实际工作,而实际从命令行调用的脚本只是向该脚本发出请求。这是一项相当多的工作,但它可能是值得的。

答案 4 :(得分:0)

我能想到的唯一解决方案是手动将您需要的各个功能复制到代码中,如果您需要执行的内容足够小。

如果您需要有关如何执行此操作的帮助,请在评论中提问。

答案 5 :(得分:0)

易。

使用cmd模块编写自己的简单shell,并使用runpy模块运行脚本。在shell程序中导入大模块,并使用init_globals

将其传递给程序

查看http://pypi.python.org/pypi/cmd2/的文档,应该很清楚如何编写自己的简单shell,即使它只有两个命令,一个用于编辑文件,一个用于运行它。

runpy是Python标准库http://docs.python.org/library/runpy.html的一部分,您可能不需要它,但知道导入和模块加载机制可以被命令shell控制甚至修改是很有用的。

你有没有想过在执行像var1 = 25这样的事情时,名字“var1”会去哪里?当您稍后执行var1时,Python如何找到print var1引用的内容?答案是这些名称都在字典中,如果您了解Python字典是什么以及它们可以做什么,这似乎是将名称与值连接的问题的明显解决方案。但还有更多。 Python可以有很多名称空间,你可以像操作字典一样操作这些名称空间。阅读此http://www.diveintopython.net/html_processing/locals_and_globals.html以了解localsglobals命名空间。这是另一个有助于http://lucumr.pocoo.org/2011/2/1/exec-in-python/

的讨论

在此问题globals and locals in python exec()中使用exec进行游戏,直到您了解其工作原理为止。然后构建命令shell以在开头一次导入模块,并编写脚本以仅导入模块(如果模块尚不可用)。当从shell内部运行脚本时,模块已经存在。

答案 6 :(得分:0)

查看您的用例(从Ruby on Rails webservice调用它),最简单的方法之一是使用XML-RPC。使用python标准库中的SimpleXMLRPCServer,然后使用ruby客户端(ruby似乎在标准库中有xmlrpc)?