Python: как быть с несколькими зависимостями .pyd с одним и тем же именем?

У меня есть в моем рабочем пространстве python два модуля, которым нужен sip.pyd
Module1.pyd нужен sip.pyd (который реализует v 8.0-8.1)
Module2.pyd нужен sip.pyd (еще один файл, который реализует v6.0 )

Так что я не могу просто выбрать более новый, это не работает: я должен оставить их обоих!

(RuntimeError: the sip module implements API v6.0 but the fbx module requires API v8.1)

Как я могу импортировать модуль в расширение .pyd (dll python, нередактируемый) и указать, какой sip.pyd использовать?

Что касается обходного пути, мне удается это сделать:

  1. Один sip.pyd находится в корневом каталоге пакетов сайта.
  2. Если мне нужно импортировать модуль, которому нужен другой sip.pyd, я удаляю корневой путь из sys.path и добавляю точный путь к папке, где находится другой sip.pyd.
  3. Я могу импортировать свой модуль и восстановить предыдущий sys.path.

person gon2024    schedule 28.11.2011    source источник


Ответы (3)


Предполагая, что у вас нет фрагмента кода, требующего одновременного использования обоих файлов. Я бы рекомендовал следующее:

  • установите оба файла в 2 отдельных каталога (назовите их, например, sip-6.0 и sip-8.0), которые вы поместите в site-packages/

  • напишите файл sip_helper.py с кодом, похожим на

Содержимое sip_helper.py:

import sys
import re
from os.path import join, dirname
def install_sip(version='6.0'):
    assert version in ('6.0', '8.0'), "unsupported version"
    keep = []
    if 'sip' in sys.modules:
       del sys.modules['sip']
    for path in sys.path:
        if not re.match('.*sip\d\.\d', path):
            keep.append(path)
    sys.path[:] = keep # remove other paths
    sys.path.append(join(dirname(__file__), 'sip-%s' % version))
  • поместите sip_helper.py в site_packages (родительский каталог каталогов sip-6.0 и sip-8.0)
  • вызовите sip_helper.install_sip при запуске ваших программ
person gurney alex    schedule 28.11.2011
comment
Спасибо, это работает очень хорошо! И если у меня есть в том же коде для переключения между sip, я могу сделать: попробуйте: import ModuleX, кроме: sip_helper.install_sip() import ModuleX - person gon2024; 29.11.2011

VirtualEnv предназначен для обработки таких случаев.

virtualenv — это инструмент для создания изолированных сред Python.

Используя virtualenv, вы сможете создать 2 среды: одну с sip.pyd в версии 8.x, другую в версии 6.0.

person Cédric Julien    schedule 28.11.2011
comment
Спасибо за этот совет! поскольку я использовал другое решение, я нашел VirtualEnv очень интересным! Я уверен, что я буду использовать его где-нибудь еще, когда-нибудь. - person gon2024; 29.11.2011

Я не знаю, работает ли это (если имя модуля должно совпадать с его содержимым), но нельзя ли просто переименовать их в sip6.pyd соответственно. sip8.pyd, а затем выполните

if need6:
    import sip6 as sip
else:
    import sip8 as sip

?

person glglgl    schedule 28.11.2011