Автозагрузка в Python

В прошлом я использовал средство perl 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, и это кажется мне действительно полезным, но это меня поражает как пограничный и интересует, можно ли это рассматривать как хорошую практику, плохую практику или подобное.

Спасибо!

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

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

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