2

我必须将参数传递给 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)。请告诉我哪里出错了。欢迎任何帮助。

4

2 回答 2

3

恕我直言,最简单的方法是制作_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.

于 2017-05-12T15:39:26.363 回答
0

Conceptually, you've written something like this (in this e.g., 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

So the class is written to save the variable var when an instance of MyClass is created. However, by the time the function finishes, the variable is destroyed, and since the class only returns a class definition and not a class instance, an instance of MyClass does not get created by the time the original variable var is destroyed, and thus the variable var never actually gets saved by MyClass.

INSTEAD, you can add var as an argument to the MyClass.__init__ function, and create a generator class to handle creation of MyClass instances, like so:

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)
于 2017-05-12T15:00:27.083 回答