6

我希望能够将实例变量添加到我的子类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'

http.server.BaseHTTPRequestHandler的上述文档说:

所有相关信息都存储在处理程序的实例变量中。子类不需要重写或扩展该__init__()方法。

但我没有看到另一种方法来做到这一点。可能吗?

4

1 回答 1

1

文档说

处理程序将解析请求和标头,然后调用特定于请求类型的方法。

事实证明,http.server.BaseHTTPRequestHandler最终继承自socketserver.BaseRequestHandler, 和socketserver.BaseRequestHandler.__init__()(定义在这里)调用do_GET()。所以问题是实例变量实际上是在do_GET()已经被调用之后设置的。

因此,为了完成这项工作,您需要将该行移到该self.pathobj行上方super(),然后重写它以执行BaseHTTPRequestHandler构造的解析self.path

于 2021-07-09T22:16:14.133 回答