Python 3.x 相对于程序/脚本位置加载站点包的Python机制?

Python 3.x 相对于程序/脚本位置加载站点包的Python机制?,python-3.x,virtualenv,pythonpath,Python 3.x,Virtualenv,Pythonpath,对于用大多数语言编写的一组程序(例如C),脚本通常可以在动态链接库之间不受任何干扰的情况下运行这些程序,并且只要它们都在PATH上,就不需要特殊的手持。也就是说,以下措施将起作用: #!/bin/bash prog1 prog2 prog3 但是,如果这三个程序是用Python编写的,并且它们导入了冲突的包版本,那么要成功运行每个程序,必须将其安装到virtualenv中,或者每个程序都必须有一个单独的站点包目录,该目录由PYTHONPATH引用。无论哪种方式,他们都需要一个设置,在运行前可能

对于用大多数语言编写的一组程序(例如C),脚本通常可以在动态链接库之间不受任何干扰的情况下运行这些程序,并且只要它们都在PATH上,就不需要特殊的手持。也就是说,以下措施将起作用:

#!/bin/bash
prog1
prog2
prog3
但是,如果这三个程序是用Python编写的,并且它们导入了冲突的包版本,那么要成功运行每个程序,必须将其安装到virtualenv中,或者每个程序都必须有一个单独的站点包目录,该目录由PYTHONPATH引用。无论哪种方式,他们都需要一个设置,在运行前可能需要拆除。也就是说,对于virtualenv:

#!/bin/bash
source $PROG1_ROOT/bin/activate
prog1
deactivate
source $PROG2_ROOT/bin/activate
prog2
deactivate
source $PROG3_ROOT/bin/activate
prog3
deactivate
对于单独的站点包:

#!/bin/bash
export PYTHONPATH=$PROG1_ROOT/lib/python3.6/site-packages
prog1
export PYTHONPATH=$PROG2_ROOT/lib/python3.6/site-packages
prog2
export PYTHONPATH=$PROG3_ROOT/lib/python3.6/site-packages
prog3
这个问题的原因是

导入pkg_资源

(至少通过Python3.6)当一个包的多个版本共享同一个站点包目录时,无法可靠地导入正确的版本,即使在它前面列出了所有版本限制

我突然想到,如果可以指定PYTHONPATH,或一些等效的,相对于程序的而不是$PWD,并且观察到目录布局的一致性,那么只需要设置一次。也就是说,如果prog1位于$prog1_ROOT/bin中,并且其库位于$prog1_ROOT/lib/python3.6/site-packages中,那么将PYTHONPATH设置为“./lib/python3.6/site-packages”不仅适用于prog1,还适用于prog2、prog3,以及通过progN需要的更多功能

然而,PYTHONPATH通常是作为绝对路径提供的,我相信相对路径是关于$PWD的,而不是python程序(prog1)。是否有其他Python路径变量具有所需的属性?如果不能做到这一点,是否有某种类型的文件可以放入$PROG1_ROOT/bin中,python程序在启动时通常会拾取该文件,并可以指示它使用$PROG1_ROOT/lib/python3.6/site-packages?在该文件中使用相对路径或绝对路径是可以的,尽管前者仍然是首选路径,因为这样可以将整个PROG1_根目录树移动到文件系统中的另一个位置,而无需重写此特殊文件。我真的希望避免需要修改prog1等自身的解决方案(例如,示例中的prog1)

谢谢

编辑:

我写道:


实施其中一些想法。在这一点上,它是特定于Linux(或至少是POSIX)的。它通过更改第一行来略微修改包的“bin”目录中的python脚本,并使用替换的本机二进制文件“包装”该目录中的所有内容,该二进制文件将自定义PYTHONPATH注入到真正目标的环境中。该二进制文件使用libSDL2中的函数查找其位置,然后指定相对于该位置的PYTHONPATH。到目前为止,它运行得非常好,安装的python包中的“程序”(bin目录的内容)与其他任何程序一样,都是基于路径运行的,而不是在shell中使用PYTHONPATH。创建相对于可执行文件的搜索路径是一个非常糟糕的主意(TM)。移动可执行文件或库,一切都会变得一团糟。一些有进取心的恶棍可能会注意到路径设置,并将一个脚本放在适当的位置,以便使用他们自己修改过的库(或有缺陷的旧版本)。等等


清理行为不端的脚本。通过使用旧版本,他们很可能会受到到目前为止已修复的安全嘘声或其他错误行为的攻击。或者找到一种方法来加载脚本本身中的内容。

思想实验-让操作系统中的每个程序都用python编写,让许多程序都有冲突的包版本,这样它们就不能驻留在单个站点包目录中。它们要么需要在virtualenv中,要么有特定的pythonpath。这个系统使用起来会非常不愉快,因为人们永远不能仅仅执行一个命令。人们总是需要掌握特殊信息,应用它,运行命令,有时还要在之后停用。“清理”这一数量的包裹是不会发生的。那么,如何让“prog1”一直运行呢?