2

Мне нужно передать параметр в класс SimpleHTTPRequestHandler, поэтому я использовал фабрику классов для создания настраиваемого обработчика, как показано ниже.Параметр доступа к SimpleHTTPRequestHandler

def RequestHandlerClass(application_path):  

    class CustomHandler(SimpleHTTPRequestHandler): 

    def __init__(self, request, client_address, server): 

     SimpleHTTPRequestHandler.__init__(self, request, client_address, server) 
     self._file_1_done = False 
     self._file_2_done = False 
     self._application_path = application_path 

    def _reset_flags(self): 

     self._file_1_done = False 
     self._file_2_done = False 

    def do_GET(self): 

     if (self.path == '/file1.qml'): 
      self._file_1_done = True 

     if (self.path == '/file2.qml'): 
      self._file_2_done = True 

     filepath = self._application_path + '/' + self.path # Error here 

     try: 
      f = open(filepath) 
      self.send_response(200) 
      self.end_headers() 
      self.wfile.write(f.read()) 
      f.close() 
     except IOError as e : 
      self.send_error(404,'File Not Found: %s' % self.path)  


     if (self._file_1_done and self._file_2_done): 
      self._reset_flags() 
      self.server.app_download_complete_event.set() 
    return CustomHandler 

Это мой HTTPServer используя пользовательский обработчик

class PythonHtpServer(BaseHTTPServer.HTTPServer, threading.Thread): 

    def __init__(self, port, serve_path): 
    custom_request_handler_class = RequestHandlerClass(serve_path) 
    BaseHTTPServer.HTTPServer.__init__(self, ('0.0.0.0', port), custom_request_handler_class) 
    threading.Thread.__init__(self) 
    self.app_download_complete_event = threading.Event() 

    def run(self): 
    self.serve_forever() 

    def stop(self): 
    self.shutdown()  

и я запустить сервер с

http_server = PythonHtpServer(port = 8123, serve_path = '/application/main.qml') 

запускает сервер, но я получаю эту ошибку

AttributeError: CustomHandler instance has no attribute '_application_path' 

В основном, из-за ошибки сервер но я не знаю, почему он не создает атрибуты (или init не вызывается). Скажите, пожалуйста, где я ошибаюсь. Любая помощь приветствуется.

ответ

0

Концептуально, вы написали что-то вроде этого (в этом, например, application_path ~ = var):

def createClass(var): 
    class MyClass: 
     def __init__(self): 
      self.var = var 
     def func(self): 
      # use var in some way 
      print (self.var) 
    # Return class definition 
    return MyClass 

Так класс написано, чтобы сохранить переменную varкогда экземпляр MyClass создается , Однако, к тому времени функции заканчивается, переменные уничтожаются, а так как класс только возвращает класс определения, а не класс экземпляра, экземпляр MyClass не получает созданное во время первоначального переменных var и, следовательно, переменная var никогда фактически не сохраняется на MyClass.

ВМЕСТО, вы можете добавить var в качестве аргумента функции MyClass.__init__ и создать класс генератор для обработки создание MyClass экземпляров, например:

class MyClass: 
    def __init__(self, arg1, arg2, var): 
     (self.arg1, self.arg2, self.var) = (arg1, arg2, var) 
    # Insert other methods as usual 

class MyClassGenerator: 
    def __init__(self, var): 
     self.var = var 
    def make(self, arg1, arg2): 
     return MyClass(arg1, arg2, var) 
2

ИМХО самый простой способ это сделать _application_path Статическом атрибут класса. Заявлено только во время декларации класса, и могут быть использованы прозрачно экземплярами класса:

def RequestHandlerClass(application_path):  

    class CustomHandler(SimpleHTTPRequestHandler): 

    _application_path = application_path # static attribute 

    def __init__(self, request, client_address, server): 

     SimpleHTTPRequestHandler.__init__(self, request, client_address, server) 
     self._file_1_done = False 
     self._file_2_done = False 

    def _reset_flags(self): 
     ... 

Таким образом, каждый новый экземпляр пользовательского класса обработчика будет иметь доступ к пути приложения как self._application_path.