Простой HTTP-сервер на Python. Как получить файлы? - PullRequest
0 голосов
/ 05 июля 2018

У меня есть такой код для запуска простого сервера на 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()

1 Ответ

0 голосов
/ 05 июля 2018

dir - встроенная функция. Вы пытаетесь присоединить эту функцию к строке 'index.html', отсюда и ошибка.


Причина, по которой вы, вероятно, смущены, заключается в том, что вы пытались скрыть dir со строкой, здесь:

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

Но когда вы помещаете это в определение class, это не создает глобальную переменную, которая скрывает встроенную функцию, она создает атрибут класса. Чтобы получить доступ к атрибуту класса из метода этого класса, вы должны сделать то же самое, что и с обычным атрибутом экземпляра:

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

Единственные различия между атрибутами класса и атрибутами экземпляра заключаются в том, что:

  • Все ваши экземпляры имеют один и тот же атрибут dir вместо того, чтобы каждый имел свою собственную копию.
  • Вы можете получить к нему доступ как RequestHandler.dir или type(self).dir вместо self.dir.

Чтобы избежать такого рода путаницы, рекомендуется избегать повторного использования имен любых встроенных функций. Хотя это законно , это часто приводит к ошибкам, подобным этой, и усложняет отладку этих ошибок.


Кроме того, учитывая, что dir является константой во всей программе, точно так же, как hostName и hostPort, и не все это тесно связано с типом RequestHandler, возможно, вы просто хотели глобальный константа, например hostName, вместо атрибута класса.

...