18

这是我的 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。

有什么办法吗?

谢谢!

4

6 回答 6

21

稍微好一点的版本,每个实例的 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()
于 2014-11-03T22:15:56.920 回答
14

有一种方法是将属性设置为类:

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 的同一个实例

于 2013-08-26T13:20:30.963 回答
10

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

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()
于 2015-05-17T15:34:43.933 回答
1

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

由于 HTTPServer 期望处理程序是一个 RequestHandler Class,我们不能完全实例化这个类。但是我们可以给我们的子类一个__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()
于 2021-05-19T21:10:51.263 回答
0

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

在我的情况下,我有HTTPServer一个服务器类的“私有”成员,并且没有意识到 Python 会处理“私有”成员,因此server在处理程序实例中访问的相应成员实际上是在服务器类的名称前面,在 OP 的例子中是self.server._http_server__t1. 所以使用self.server._<server class name>__<private member name>而不是self.server.<member name>.

于 2021-10-19T05:23:02.673 回答
0

Aaa 和这个老问题的另一个答案,这次使用工厂函数创建 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()
于 2021-05-19T21:15:59.097 回答