我希望能够将实例变量添加到我的http.server.BaseHTTPRequestHandler的子类中。
这是我的代码:
from http.server import BaseHTTPRequestHandler, HTTPServer
import urllib
class Server(BaseHTTPRequestHandler):
def __init__(self, request, client_addr, server):
super().__init__(request, client_addr, server)
self.pathobj = urllib.parse.urlparse(self.path)
def do_HEAD(self):
self.send_response(200)
def do_GET(self):
print(self.pathobj)
self.send_response(200)
self.end_headers()
def do_POST(self):
print(self.pathobj)
self.send_response(405)
self.end_headers()
def run(server_class=HTTPServer, handler_class=Server, port=8080):
server_address = ("", port)
httpd = server_class(server_address, handler_class)
print("Starting httpd on port {}...".format(port))
httpd.serve_forever()
if __name__ == "__main__":
run()
我希望能够在每个类方法中访问ParseResult
返回的urllib.parse.urlparse
对象,而无需在每个类方法的开头重写self.pathobj = urllib.parse.urlparse(self.path)
。
上述代码不起作用 - 当调用do_GET
或do_POST
时,它会抱怨'Server' object has no attribute 'pathobj'
。
以上docs for http.server.BaseHTTPRequestHandler说:
所有相关信息都存储在处理程序的实例变量中。子类不应该覆盖或扩展
__init__()
方法。
但我没有看到另一种方法。有可能吗?
答案 0 :(得分:0)
文档说
<块引用>处理程序将解析请求和标头,然后调用特定于请求类型的方法。
事实证明,http.server.BaseHTTPRequestHandler
最终继承自 socketserver.BaseRequestHandler
,而 socketserver.BaseRequestHandler.__init__()
(定义为 here)调用 do_GET()
。所以问题是实例变量实际上是在 do_GET()
已经被调用之后设置的。
因此,为了使这项工作正常进行,您需要将 self.pathobj
行移到 super()
行上方,然后重写它以执行 BaseHTTPRequestHandler
为构造 { 所做的解析{1}}。