将参数传递给SimpleHTTPRequestHandler

时间:2016-11-21 07:39:34

标签: python python-2.7 simplehttpserver basehttpserver requesthandler

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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保存。

INSTEAD,您可以将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)