在 Python 中,要实现类似 PHP 的“请求哪个脚本就执行哪个脚本”的动态 HTTP 脚本执行机制,有几种方式可以做到。以下是一个完整的实现思路(核心思想:解析 URL 路径,根据路径动态加载并执行对应的 Python 脚本文件):
示例目标:
当访问 http://localhost:8000/hello.py,服务器执行 hello.py 并返回它的输出内容(如同 PHP 一样)。
实现方法:用 http.server + 动态加载执行
# dynamic_http_server.py
import os
import sys
import io
import traceback
from http.server import SimpleHTTPRequestHandler, HTTPServer
from urllib.parse import unquote
class DynamicScriptHandler(SimpleHTTPRequestHandler):
def do_GET(self):
path = unquote(self.path.lstrip('/'))
# 只处理 .py 脚本文件请求
if path.endswith(".py") and os.path.isfile(path):
try:
# 用独立的 namespace 执行脚本
stdout = io.StringIO()
sys.stdout = stdout
script_globals = {"__name__": "__main__"}
with open(path, 'r', encoding='utf-8') as f:
code = f.read()
exec(code, script_globals)
output = stdout.getvalue()
sys.stdout = sys.__stdout__
# 返回结果
self.send_response(200)
self.send_header("Content-type", "text/plain; charset=utf-8")
self.end_headers()
self.wfile.write(output.encode('utf-8'))
except Exception as e:
sys.stdout = sys.__stdout__
self.send_response(500)
self.end_headers()
self.wfile.write(f"Error executing {path}:\n{traceback.format_exc()}".encode('utf-8'))
else:
# 默认静态文件处理
super().do_GET()
if __name__ == '__main__':
port = 8000
print(f"Serving on http://localhost:{port}/")
httpd = HTTPServer(('', port), DynamicScriptHandler)
httpd.serve_forever() 示例 hello.py 脚本:
print("Hello from Python script!") 运行方式:
python dynamic_http_server.py
然后访问:
http://localhost:8000/hello.py
补充说明:
| 动态脚本解析 | ✅(像 PHP 一样执行 .py 脚本) |
| 脚本输出到前端 | ✅(print 输出将返回给浏览器) |
| 安全性 | ⚠️ 极低(不建议在公网使用,容易被任意执行命令) |
| POST/参数支持 | ❌ 默认不支持(可扩展) |
如果你想做成类似 PHP-CGI 的生产用法(推荐):
考虑用:
FastAPI + exec() 动态执行脚本;
uWSGI or Gunicorn + 定制化调度逻辑;
自定义 sandbox 环境(限制导入模块、输出内容等);
如你有安全考虑或想支持 POST 参数,也可以告诉我,我可以升级这个架构支持完整的 GET/POST 参数解析、路径路由转发、沙箱执行 等功能。是否需要?
网友回复


