具有自定义实例的BaseHTTPRequestHandler



这是我的http服务器:

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
class test:
    def show(self):
        return "aaaa"
class http_server:
    def __init__(self, t1):
        self.t1 = t1
        server = HTTPServer(('', 8080), myHandler)
        server.serve_forever()
class myHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write(self.t1.show()) #Doesnt work
        return
class main:
    def __init__(self):
        self.t1 = test()
        self.server = http_server(self.t1)
if __name__ == '__main__':
    m = main()

我需要访问myHander内部的实例t1。

有什么方法可以做吗?

谢谢!

稍微好一点的版本,其中t1对于每个实例都不相同。

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
class test:
    def show(self):
        return "aaaa"
class http_server:
    def __init__(self, t1):
        def handler(*args):
            myHandler(t1, *args)
        server = HTTPServer(('', 8080), handler)
        server.serve_forever()
class myHandler(BaseHTTPRequestHandler):
    def __init__(self, t1, *args):
        self.t1 = t1
        BaseHTTPRequestHandler.__init__(self, *args)
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write(self.t1.show()) #Doesnt work
        return
class main:
    def __init__(self):
        self.t1 = test()
        self.server = http_server(self.t1)
if __name__ == '__main__':
    m = main()

有一种方法可以做到这一点,那就是将属性设置为类:

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
class test:
    def show(self):
        return "aaaa"
class http_server:
    def __init__(self, t1):
        myHandler.t1 = t1
        server = HTTPServer(('', 8080), myHandler)
        server.serve_forever()
class myHandler(BaseHTTPRequestHandler):
    t1 = None
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write(self.t1.show()) #Doesnt work
        return
class main:
    def __init__(self):
        self.t1 = test()
        self.server = http_server(self.t1)
if __name__ == '__main__':
    m = main()

您必须小心,使用myHandler的每个地方都将是t1 的同一实例

我知道我很晚才回答,但这可能对未来的观众有所帮助。有一种非常简单的方法可以访问t1,就像使用BaseHTTPRequestHandler对象的server变量所要求的那样:

from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
class test:
    def show(self):
        return "aaaa"
class http_server:
    def __init__(self, t1):
        server = HTTPServer(('', 8080), myHandler)
        server.t1 = t1
        server.serve_forever()
class myHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write(self.server.t1.show())
        return
class main:
    def __init__(self):
        self.t1 = test()
        self.server = http_server(self.t1)
if __name__ == '__main__':
    m = main()

这个8年前的问题的另一种答案是:)我也想避免使用在所有Handler对象之间共享的类变量以防万一,但我花了一分钟时间才理解@rsmoorthy的答案为什么有效。这与他的答案基本相同,但使用functools.partial来增加清晰度。

由于HTTPServer期望处理程序为RequestHandler类,因此我们无法完全实例化该类。但是,我们可以为我们的子类提供一个接受额外数据的自定义__init__,然后使用functools.partial为HTTPServer填充额外的信息。通过这种方式,它只是按照自己的意愿实例化我们的处理程序,但我们仍然可以在内部传递t1

from http.server import BaseHTTPRequestHandler, HTTPServer
import functools

class test:
    def show(self):
        return b"aaaa"
class http_server:
    def __init__(self, t1):
        handler_partial = functools.partial(Handler, t1=t1)
        server = HTTPServer(('', 8080), handler_partial)
        server.serve_forever()
class Handler(BaseHTTPRequestHandler):
    def __init__(self, *args, t1=None, **kwargs):
        # Assign before super().__init__ because init is what triggers parsing the request
        self.t1 = t1
        super().__init__(*args, **kwargs)
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write(self.t1.show())
        return
class main:
    def __init__(self):
        self.t1 = test()
        self.server = http_server(self.t1)
if __name__ == '__main__':
    m = main()

Aaan和这个老问题的另一个答案,这次使用了一个工厂函数,该函数创建了BaseHTTPRequestHandler的子类,我们的t1已经可用。

from http.server import BaseHTTPRequestHandler, HTTPServer
class test:
    def show(self):
        return b"aaaa"
class http_server:
    def __init__(self, t1):
        myHandler = handlerFactory(t1)
        server = HTTPServer(('', 8080), myHandler)
        server.serve_forever()
def handlerFactory(t1):
    class myHandler(BaseHTTPRequestHandler):
        def do_GET(self):
            self.send_response(200)
            self.send_header('Content-type','text/html')
            self.end_headers()
            self.wfile.write(t1.show())
            return
    return myHandler
class main:
    def __init__(self):
        self.t1 = test()
        self.server = http_server(self.t1)
if __name__ == '__main__':
    m = main()

遇到了同样的问题,并试图遵循@XaF的答案;由于冷却点值低,无法发表评论,请在下面添加答案。

在我的例子中,我将HTTPServer作为服务器类的"private"成员,但没有意识到Python会处理"private(私有)"成员,因此在处理程序的server实例中访问的相应成员实际上是以服务器类的名称为前缀的,在OP的例子中是self.server._http_server__t1。因此使用self.server._<server class name>__<private member name>而不是self.server.<member name>

相关内容

  • 没有找到相关文章

最新更新