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()

Мне нужно получить доступ к экземпляру t1 внутри myHander.

Есть ли способ, как это сделать?

Спасибо!

6 ответов

Решение

Есть способ установить это свойство для класса:

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 не будет одинаковым для каждого экземпляра.

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()

Я знаю, что отвечаю довольно поздно, но это может быть полезно для будущих зрителей. Есть действительно простой способ доступа 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()

Еще один вариант ответа на этот вопрос 8-летней давности :) Я тоже хотел на всякий случай избежать использования переменных класса, которые используются во всех объектах Handler, но мне потребовалась минута, чтобы понять, почему ответ @ rsmoorthy сработал. Это в основном тот же ответ, что и его, но используется для большей ясности.

Поскольку 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()

Аааи еще один ответ на этот старый вопрос, на этот раз с использованием фабричной функции, которая создает подклассы 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 как член класса сервера, а соответствующий член доступен в server к экземпляру обработчика добавляется имя класса сервера, которое в примере OP будет self.server._http_servert1. Так что используйте self.server._<server class name><member name> вместо того self.server.<member name>.

Другие вопросы по тегам