从python调用python - 模块导入的持久性?

时间:2009-05-19 14:43:39

标签: python import module

所以我有一些Python脚本,我有一个BaseHTTPServer来提供他们的响应。如果请求的文件是.py,那么我将使用execfile(script.py)运行该脚本。

问题在于:有关于进口的特殊规定吗?一个脚本只需运行一次,最好在请求之间保持它创建的对象。我能相信这会发生吗?

通过execfile()运行的脚本运行方式是否有所不同,或者是否有任何范围访问问题?

2 个答案:

答案 0 :(得分:2)

execfile方法的文档是here。由于没有指定特定版本的python,我将假设我们正在谈论2.6.2。

execfile的文档指定它需要三个参数:文件名,字典(充当局部变量)和第二个字典(充当全局变量)。如果省略第二个和第三个参数,则文件的内容在它们自己的范围(如模块)中运行,该范围捕获局部变量但将全局变量公开给父范围。因此,如果文件创建局部变量,则不会保留它们,但会保留全局变量。

但是,运行没有指定本地和全局上下文的execfile意味着该文件会看到调用函数的locals和globals。对于您不信任的代码,这应该被视为安全漏洞。为locals和globals创建两个字典通常是明智的,并将这些字典作为execfile的第二个和第三个参数传递。如果你将这些词典保存在某个地方(例如在另一个由文件名键入的词典中),那么你可以在下次提供文件时重复使用这些词典,这将使文件创建的对象保持活动状态。

简而言之:execfile与导入不完全相同。但是你可以保留locals和globals的字典来保持execfile调用的结果再次被使用。

答案 1 :(得分:1)

我建议不要使用execfile。相反,您可以使用内置__import__函数动态导入他们作为模块请求的python文件。这是我刚刚编写和测试的一个完整的,有效的例子:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()

        filename = self.path.lstrip("/")
        self.wfile.write("You requested " + filename + "\n\n")
        if filename.endswith(".py"):
            pyname = filename.replace("/", ".")[:-3]
            module = __import__(pyname)
            self.wfile.write( module.do_work() )

HTTPServer(("",8080), Handler).serve_forever()

因此,在这种情况下,如果有人访问http://localhost:8080/some_page,则会打印“您请求some_page”。

但是如果您请求http://localhost:8080/some_module.py,那么文件some_module.py将作为Python模块导入,并且将调用该模块中的do_work函数。因此,如果该模块包含代码

def do_work():
    return "Hello World!"

并且您提出了该请求,然后结果页面将是

You requested some_module.py

Hello World!

这应该是处理此类事情的良好起点。顺便说一句,如果您发现自己想要更高级的Web服务器,我强烈推荐CherryPy