Модуль Python не определен в модуле при использовании пользовательской функции загрузки

Рассмотрим следующую программу для загрузки всех модулей в каталоге:

import pkgutil
import os.path
import sys

def load_all(directory):
    for loader, name, ispkg in pkgutil.walk_packages([directory]):
        loader.find_module(name).load_module(name)

if __name__ == '__main__':
    here = os.path.dirname(os.path.realpath(__file__))
    path = os.path.join(here, 'lib')
    sys.path.append(path)
    load_all(path)

Теперь рассмотрим, что у нас есть следующие файлы.

Библиотека / магия / imho.py:

"""This is an empty module.
"""

Библиотека / магия / wtf.py:

import magic.imho
print "magic contents:", dir(magic)

Библиотека / магия / __ init__.py:

"Empty package init file"

При выполнении программы выше, это выдает:

magic contents: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

Другими словами, несмотря наimport magic.imho нет атрибутаimho на упаковкеmagic что вызывает любые последующие ссылки наmagic.imho терпеть неудачу.

Запуск одного и того же кода (более или менее) непосредственно в python показывает другой вывод, который я ожидал от запуска программы загрузки.

$ PYTHONPATH=lib ipython
Python 2.7.6 (default, Mar 22 2014, 22:59:38) 
Type "copyright", "credits" or "license" for more information.

IPython 1.2.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import magic.wtf
magic contents: ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'imho']

Почему есть разница?

Обновить: Дело в том, что символmagic.imho не существует внутриmagic.wft несмотря на то, что он был явно импортирован. Итак, что нужно сделать с пользовательской процедурой загрузки, чтобы она работала правильно и чтобы символявляется видимый после того, как он был импортирован вmagic.wtf.

Решение с использованиемsetattr: BartoszKP дал решение ниже, используяexec назначить значение для пакета. Так как я обычно не люблю использоватьexec (по многим причинам инъекции являются первыми) я использовалsetattr а такжеrpartition следующее:

def load_all(directory):
    for loader, name, ispkg in pkgutil.walk_packages([directory]):
        module = loader.find_module(name).load_module(name)
        pkg_name, _, mod_name = name.rpartition('.')
        if pkg_name:
           setattr(sys.modules[pkg], mod_name, module)

Ответы на вопрос(1)

Ваш ответ на вопрос