Автозагрузка в Python - PullRequest
16 голосов
/ 21 июня 2009

Раньше я использовал утилиту perol AUTOLOAD для реализации отложенной загрузки символов в пространство имен и хотел такую ​​же функциональность в python.

Традиционно самым близким, по-видимому, вам является использование класса и класса __getattr__ для достижения такого рода вещей. Однако я также попытался покопаться в sys.modules и придумал:

# mymod.py
def greet(greeting="Hello World"):
   print greeting

class autoload(object):
    def __init__(self, __name__):
        super(autoload, self).__init__()
        self.wrapped_name = __name__
        self.wrapped = sys.modules[__name__]
    def __getattr__(self, name):
        try:
            return getattr(self.wrapped, name)
        except AttributeError:
            def f():
                greet(name+" "+self.wrapped_name)
            return f

if __name__ != "__main__":
    import sys
    sys.modules[__name__] = autoload(__name__)

Это работает так, как я хотел бы с точки зрения пользователя:

~> python
Python 2.5.1 (r251:54863, Jan 10 2008, 18:01:57)
[GCC 4.2.1 (SUSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import mymod
>>> mymod.hello()
hello
>>> from mymod import Hello_World
>>> Hello_World()
Hello_World

Но меня это поразило - есть ли стандартный подход, который люди обычно используют для автозагрузки в python?

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

Спасибо!

Ответы [ 3 ]

10 голосов
/ 21 июня 2009

«Ленивый импорт» может быть построен поверх «ловушек импорта», указанных в PEP 302 , и теперь полностью реализован. PEP 369 использовался для охвата «отложенного импорта», а также для ловушек после импорта, но с тех пор был упрощен и теперь охватывает только крючки после импорта; Тем не менее, вас может заинтересовать оригинальный проект .

Хорошую реализацию "отложенного импорта" через meta_path можно найти в этом рецепте .

1 голос
/ 05 мая 2017

Чтобы ответить на вопрос об использовании класса для олицетворения модуля:

Да, функциональность не случайна. Он был там с самого начала в серии 2.x и до сих пор работает в серии 3.x.

Чтобы ответить на вопрос о ленивой загрузке:

Есть несколько способов сделать это, и каждый будет немного загадочным. Использование имитатора модуля - хороший метод.

0 голосов
/ 22 июня 2009

Нет, я не думаю, что это полезно.

Зачем создавать на лету функцию для каждого атрибута, который вы пытаетесь получить из модуля? Кажется, смущает меня. Похоже, что новые функции создаются магией, поэтому нужно глубоко изучить реализацию, чтобы понять, что происходит. И все это без синтаксической выгоды.

И даже если у вас была веская причина для этого, зачем делать это с модулем? Зачем регистрировать свой экземпляр класса в sys.modules? Я думаю, что создание вещей, которых они не представляют, не одобряется в python.

Если вы специально не запутываете код, я не понимаю, зачем все это делать.

...