这让我感到困惑了一段时间。我正在尝试创建一个非常简单的类似REST的接口(不使用第三方库,我知道这些库可用)。
它背后的想法是我可以有一个目录,例如mylib
,我可以在其中放入python文件,如do_something.py
,并通过POST到http://localhost/do_something代码将进入生活并做点什么!
文件内容如下。
example.py
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
import json, logging
from mylib import my_module
class MyRequestHandler (BaseHTTPRequestHandler):
# Send JSON responses
# -----------
def send_json(self, json_message, response_code=200):
self.send_response(response_code)
self.send_header('Content-type', 'application/json')
self.end_headers()
self.request.sendall(json.dumps(json_message).encode())
# Get JSON requests
# ----------
def get_json(self):
body = self.rfile.read(int(self.headers.get('Content-Length')))
if (body):
try:
receivedData = json.loads(body.decode())
except:
self.send_json({"Status": "Error", "Message": "Invalid JSON received"}, 400)
receivedData = None
else:
receivedData = None
return receivedData
# POST
# ---------
def do_POST(self):
module_to_call = (self.path).replace('/', '.')[1:]
if module_to_call.endswith('.'): # Remove trailing dot
module_to_call = module_to_call[:-1]
print("Path is: '" + module_to_call + "'")
# invoke function
module_to_call = getattr(self, module_to_call)
response = module_to_call()
self.send_json(response)
# GET
# --------
def do_GET(self):
pass
# -----------------------------------------------------------------------------
# Server startup code
# -------------------
def start_server():
# Begin serving
# -------------
port = 8003
server = HTTPServer(('', port), MyRequestHandler)
print(("Server now running on port {0} ...").format(port))
server.serve_forever()
# -----------------------------------------------------------------------------
# Start the Server
# ----------------
if __name__ == '__main__':
start_server()
my_module.py
def my_module():
print("Hello World!")
return{'Greeting': 'Hello World!'}
当我启动服务器并尝试POST到http://localhost:8003/my_module时,我得到以下输出:
Server now running on port 8003 ...
Path is: 'my_module'
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 59541)
Traceback (most recent call last):
File "C:\Users\Test\AppData\Local\Programs\Python\Python35-32\lib\socketserver.py", line 313, in _handle_request_noblock
self.process_request(request, client_address)
File "C:\Users\Test\AppData\Local\Programs\Python\Python35-32\lib\socketserver.py", line 341, in process_request
self.finish_request(request, client_address)
File "C:\Users\Test\AppData\Local\Programs\Python\Python35-32\lib\socketserver.py", line 354, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "C:\Users\Test\AppData\Local\Programs\Python\Python35-32\lib\socketserver.py", line 681, in __init__
self.handle()
File "C:\Users\Test\AppData\Local\Programs\Python\Python35-32\lib\http\server.py", line 422, in handle
self.handle_one_request()
File "C:\Users\Test\AppData\Local\Programs\Python\Python35-32\lib\http\server.py", line 410, in handle_one_request
method()
File ".\example.py", line 43, in do_POST
module_to_call = getattr(self, module_to_call)
AttributeError: 'MyRequestHandler' object has no attribute 'my_module'
----------------------------------------
这很有道理,因为' MyRequestHandler"没有属性" my_module"!我无法解决的问题是如何解决这个问题?
我应该通过" mylib"进入MyRequestHandler?我应该在类中执行导入(但是该功能只能在类中使用)?
我试图保持简洁,所以即使是Python新手(就像我好像!)也可以写一个独立的脚本,将其放入" mylib"和一切"只是工作"。新手可以访问他们脚本的网址,让它神奇地运行。
感谢任何帮助或建议。
答案 0 :(得分:2)
使用__import__()
方法:
temp = __import__('mylib', globals(), locals(), ['module_to_call'], -1)
response = temp.module_to_call()
我在工作中使用2.6,这通常被那些使用2.7的人使用,因为importlib模块在3中更强大。如果你使用3,你可以执行以下操作:
from importlib import import_module
temp = import_module('mylib')
但现在你必须使用getattr来获得你想要调用的函数
func_to_call = getattr(temp, 'module_to_call')
response = func()
或者您可以在另一个模块中使用函数字典,但随着字典的增长,这将需要大量的工作。