导入twisted.web服务器时的问题
我刚开始学习使用twisted.web,遇到了一些问题,就是在一个.rpy
脚本中导入Python模块时出错。
在C:\py\twisted\mysite.py
文件里,我写了这个:
from twisted.web.resource import Resource
from twisted.web import server
class MySite(Resource):
def render_GET(self, request):
request.write("<!DOCTYPE html>")
request.write("<html><head>")
request.write("<title>Twisted Driven Site</title>")
request.write("</head><body>")
request.write("<h1>Twisted Driven Website</h1>")
request.write("<p>Prepath: <pre>{0}</pre></p>".format(request.prepath))
request.write("</body></html>")
request.finish()
return server.NOT_DONE_YET
而在C:\py\twisted\index.rpy
文件里,我写了这个:
import mysite
reload(mysite)
resource = mysite.MySite()
我在命令提示符下运行了twistd -n web --port 8888 --path C:\py\twisted
,服务器成功启动了。但是当我访问localhost:8888
时,出现了一个(很长的)错误信息,提示是ImportError:
<type 'exceptions.ImportError'>: No module named mysite
我可以在解释器中导入这个模块,如果我直接把index.rpy
当作Python脚本执行,就不会出现导入错误。关于这个问题的文档有点模糊,只是说“不过,通常在Python模块中定义资源子类会更好。为了让模块中的更改生效,你必须重启Python进程,或者重新加载模块。”(来自这里)。
有没有人知道正确的做法是什么?
1 个回答
简单来说,你需要把 PYTHONPATH 设置为包含 C:\py\twisted
。
详细说说...
一个 rpy 脚本其实就是一些 Python 代码,和其他 Python 代码没什么区别。所以在 rpy 脚本里的导入(import)和其他 Python 代码里的导入是一样的。最常见的情况是,系统会一个一个地检查 sys.path
里的目录,按照顺序来,如果找到一个和你导入的名字匹配的 .py
文件,就会用这个文件来定义模块。
sys.path
主要是通过一些固定的定义来填充的,比如 C:\Python26\Lib\ 这些路径,还有 PYTHONPATH
环境变量。不过,有一点额外的事情需要知道。当你运行 "python" 时,当前的工作目录会被加到 sys.path
的最前面。当你运行 "python C:\foo\bar\baz.py" 时,C:\foo\bar\
会被加到 sys.path
的最前面。但是当你运行 "twistd ..." 时,sys.path
并不会添加任何有用的东西。
这种最后的行为可能解释了为什么当你直接运行 rpy 脚本,或者在 Python 中交互式地导入模块时测试能成功,但用 twistd 时却失败。把 C:\py\twisted
加到 PYTHONPATH
环境变量中,应该能让模块在你用 twistd 启动的服务器上运行 rpy 脚本时被导入。