Перенаправить модуль Python в другой каталог (под-версию) при импорте - PullRequest
1 голос
/ 10 апреля 2020
mypkg/
├── mypkg-1_0_0/
│   ├── __init__.py
├── __init__.py

Приведенный выше каталог является примером того, как выглядит мой каталог модулей. Мастер-модуль mypkg содержит все подверсии. Когда я делаю import mypkg, файл __init__ предназначен для перенаправления импорта в правильную версию при запуске файла целевых версий __init__, а также установки атрибутов на globals()

Вот что __init__.py в mypkg выглядит следующим образом:

def __load():
    import os

    pkgrelease = "mypkg-1_0_0"

    if pkgrelease:
        current_path = __path__[0]

        new_path = os.path.join( current_path, pkgrelease )
        init_path = os.path.join( new_path, "__init__.py" )

        __path__[:] = [new_path]

        initf = open( init_path )
        exec compile( initf.read(), init_path, "exec" ) in globals()
        initf.close()

    else:
        raise ImportError( "Could not find [%s] package version" % os.path.basename(__path__) )

__load()

del __load

В python2 все работает нормально, пакет перенаправляется на версию 1_0_0 и все такое, как __version__ в этом файле __init__ версий, сохраняются и устанавливаются в globals(). Но я также знаю, что есть гораздо лучший способ сделать то, что я пытаюсь достичь, это кросс-совместимость. Это не будет работать в python3 из-за оператора exe c compile.

1 Ответ

0 голосов
/ 11 апреля 2020

Я нашел одно решение, которое работает на обоих py2 / 3. Просто нужно настроить функцию exec, чтобы получить globals() аргумент. Это показано здесь, в документах . Вот исправленный код:

def load():
    import os

    pkgrelease = "mypkg-1_0_0"

    current_path = __path__[0]

    new_path = os.path.join( current_path, pkgrelease )
    init_path = os.path.join( new_path, "__init__.py" )

    __path__[:] = [new_path]
    initf = open(init_path)
    module = compile(initf.read(), init_path, "exec")
    exec(module, globals())
    initf.close()


load()

del load

...