Вызов python из python - постоянство импорта модулей? - PullRequest
2 голосов
/ 19 мая 2009

Итак, у меня есть несколько скриптов на Python, и у меня есть BaseHTTPServer для обслуживания их ответов. Если запрошенный файл - .py, тогда я запустите этот скрипт, используя execfile (script.py).

Вопрос в следующем: существуют ли какие-либо особые правила в отношении импорта? Один скрипт должен запускаться только один раз, и было бы хорошо сохранить объекты, которые он создает, живыми между запросами. Могу ли я верить, что это произойдет?

Сценарий, выполняемый через execfile (), выполняется по-другому, или есть проблемы с доступом к области действия?

Ответы [ 2 ]

2 голосов
/ 19 мая 2009

Документация для метода execfile: здесь . Поскольку не указана конкретная версия python, я предполагаю, что речь идет о 2.6.2.

В документации для execfile указано, что она принимает три аргумента: имя файла, словарь (для локальных переменных) и второй словарь (для глобальных переменных). Если вы опустите второй и третий аргументы, содержимое файла запускается в своей собственной области (например, в модуле), которая захватывает локальные переменные, но предоставляет глобальные переменные родительской области. Поэтому, если файл создает локальные переменные, они не будут сохранены, но глобальные переменные будут сохранены.

Однако запуск execfile без указания локального и глобального контекстов означает, что файл видит локальные и глобальные переменные вызывающей функции. Для кода, которому вы не доверяете, это следует считать дырой в безопасности. Как правило, целесообразно создать два словаря для локальных и глобальных переменных и передать их в качестве второго и третьего аргументов в execfile. Если вы храните эти словари где-нибудь (например, в другом словаре, указанном по имени файла), то вы можете повторно использовать эти словари при следующем обращении к файлу, что сохранит объекты, созданные файлом, живыми.

Итак, вкратце: execfile не совсем как импорт. Но вы можете сохранить словари местных жителей и глобалов, чтобы результаты повторного вызова могли быть снова использованы.

1 голос
/ 19 мая 2009

Я рекомендую не использовать execfile. Вместо этого вы можете динамически импортировать запрашиваемый ими файл python как модуль, используя встроенную функцию __import__. Вот полный рабочий пример, который я только что написал и протестировал:

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()

        filename = self.path.lstrip("/")
        self.wfile.write("You requested " + filename + "\n\n")
        if filename.endswith(".py"):
            pyname = filename.replace("/", ".")[:-3]
            module = __import__(pyname)
            self.wfile.write( module.do_work() )

HTTPServer(("",8080), Handler).serve_forever()

Таким образом, в этом случае, если кто-то посещает http://localhost:8080/some_page, то будет напечатано "Вы запросили страницу".

Но если вы запросите http://localhost:8080/some_module.py, тогда файл some_module.py будет импортирован как модуль Python и будет вызвана функция do_work в этом модуле. Так что, если этот модуль содержит код

def do_work():
    return "Hello World!"

и вы сделаете этот запрос, тогда получится страница

You requested some_module.py

Hello World!

Это должно стать хорошей отправной точкой для таких вещей. Кроме того, если вам нужен более совершенный веб-сервер, я настоятельно рекомендую CherryPy .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...