Python:如何处理多个同名.pyd依赖?

3 投票
3 回答
1711 浏览
提问于 2025-04-17 07:14

我在我的Python工作环境里有两个模块,它们都需要用到sip.pyd这个文件。
Module1.pyd需要的是sip.pyd(这个文件实现的是8.0-8.1版本)。
而Module2.pyd需要的是另一个sip.pyd(这个文件实现的是6.0版本)。

所以我不能只选择更新的那个,因为这样不行:我必须同时保留这两个文件!

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

我该怎么导入一个.pyd扩展名的模块(这是一个Python的动态链接库,不能编辑),并指定要使用哪个sip.pyd呢?

作为一个解决办法,我是这样做的:

  1. 一个sip.pyd放在我的根目录的site-packages位置。
  2. 如果我需要导入那个需要另一个sip.pyd的模块,我就把根路径从sys.path中去掉,然后添加上另一个sip.pyd所在的具体文件夹路径。
  3. 这样我就可以导入我的模块,然后再把之前的sys.path恢复回来。

3 个回答

0

我不太确定这样做是否有效(一个模块的名字是否必须和它的内容匹配),不过你可以试着把它们重命名为 sip6.pydsip8.pyd,然后再执行

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

这样可以吗?

1

VirtualEnv 是用来解决这些问题的。

virtualenv 是一个工具,可以创建独立的 Python 环境。

使用 virtualenv,你可以创建两个环境,一个里面有 sip.pyd 的 8.x 版本,另一个则是 6.0 版本。

1

假设你不需要同时用到这两个文件,我建议你可以这样做:

  • 把这两个文件分别安装在两个不同的文件夹里,比如叫它们 sip-6.0sip-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

撰写回答