【问题标题】:Simple HTTP server in Python. How to GET files?Python 中的简单 HTTP 服务器。如何获取文件?
【发布时间】:2018-07-04 23:56:52
【问题描述】:

我有这样的代码可以在 Python 3 上运行简单的服务器。我知道我可以使用类似 python -m http.server 8080 的东西,但是我想了解它是如何工作的并设置服务文件扩展名的限制。

我尝试使用path.join(dir, 'index.html'),但看起来不起作用。

>> TypeError: join() argument must be str or bytes, not 'builtin_function_or_method'

from http.server import BaseHTTPRequestHandler, HTTPServer
from os import path

hostName = "localhost"
hostPort = 8080

class RequestHandler(BaseHTTPRequestHandler):
    dir = path.abspath(path.dirname(__file__))
    content_type = 'text/html'

    def _set_headers(self):
        self.send_response(200)
        self.send_header('Content-Type', self.content_type)
        self.send_header('Content-Length', path.getsize(self.getPath()))
        self.end_headers()

    def do_GET(self):
        self._set_headers()
        self.wfile.write(self.getContent(self.getPath()))

    def getPath(self):
        if self.path == '/':
            content_path = path.join(dir, 'index.html')
        else:
            content_path = path.join(dir, str(self.path))
        return content_path

    def getContent(self, content_path):
        with open(content_path, mode='r', encoding='utf-8') as f:
            content = f.read()
        return bytes(content, 'utf-8')

myServer = HTTPServer((hostName, hostPort), RequestHandler)
myServer.serve_forever()

【问题讨论】:

  • 永远不要覆盖内置名称(在您的示例中为 dir)。使用对读者更有帮助的东西 (BASE_DIRECTORY) 或类似的东西。
  • 这是一个简单的范围界定问题。在 python 中,您无法访问其函数内的类的范围。

标签: python python-3.x webserver httpserver simplehttpserver


【解决方案1】:

dir 是一个内置函数。您正在尝试将该函数加入字符串 'index.html',因此出现错误。


您可能感到困惑的原因是您试图在这里用字符串隐藏dir

dir = path.abspath(path.dirname(__file__))

但是当你把它放在class 定义中时,它不会创建一个隐藏内置函数的全局变量,它会创建一个类属性。要从该类的方法中访问类属性,您必须执行与普通实例属性相同的操作:

content_path = path.join(self.dir, 'index.html')

类属性和实例属性的唯一区别是:

  • 您的所有实例共享相同的dir 属性,而不是每个实例都有自己的副本。
  • 您可以使用RequestHandler.dirtype(self).dir 而不是self.dir 访问它。

为避免这种混淆,最好避免重用任何内置函数的名称。虽然这样做是合法,但它经常会导致类似这样的错误,并且使调试这些错误变得更加困难。


另外,鉴于 dir 是整个程序中的常量,就像 hostNamehostPort 一样,并且与 RequestHandler 类型没有那么紧密的联系,也许你只是想要一个全局常量,例如 hostName,而不是类属性。

【讨论】:

  • @MAxShvedov 抱歉,我不明白你问的这个问题是什么意思。
  • 我的意思是如果我将dir_path = path.abspath(path.dirname(__file__))用作全局常量,应该如何从类中调用它?
  • @MAxShvedov 与使用任何全局的方式完全相同:只需引用名称 dir_path
  • 好的,谢谢。看来我赶时间了。代码适用于index.html,如果它只是请求/,但对于其他文件它不起作用。这就是尝试从c:/ 目录请求文件的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多