将新的实例变量添加到http.server.BaseHTTPRequestHandler的子类

时间:2017-05-08 18:47:23

标签: python-3.x http basehttprequesthandler

我希望能够将实例变量添加到我的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_GETdo_POST时,它会抱怨'Server' object has no attribute 'pathobj'

以上docs for http.server.BaseHTTPRequestHandler说:

  

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

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

1 个答案:

答案 0 :(得分:0)

文档说

<块引用>

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

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

因此,为了使这项工作正常进行,您需要将 self.pathobj 行移到 super() 行上方,然后重写它以执行 BaseHTTPRequestHandler 为构造 { 所做的解析{1}}。