Python使用PYTHONPATH
环境变量来确定它应该在哪些文件夹中查找模块。
您可以通过修改sys.path
来解决它,它适用于纯Python模块。
但是当一个模块使用共享对象文件或静态库时,它会在LD_LIBRARY_PATH
(在linux上)中查找它们,但是根据我所知,这不能轻易改变并且与平台有关。
这个问题的快速解决当然是设置环境变量或调用像LD_LIBRARY_PATH=. ./script.py
这样的脚本,但是你必须为你打开的每个新shell再次设置它。
此外,我的案例中的.so
文件将始终与.py
文件位于同一目录中,但很可能会移动到另一个绝对路径,所以我想每次都自动设置它们我调用了脚本。
如何编辑Python解释器在运行时独立查找库平台的路径?
我已经尝试了os.environ['LD_LIBRARY_PATH'] = os.getcwd()
,但无济于事。
答案 0 :(得分:19)
我会用:
import os
os.environ['LD_LIBRARY_PATH'] = os.getcwd() # or whatever path you want
这将LD_LIBRARY_PATH
环境变量设置为仅执行当前进程的持续时间/生命周期。
编辑:看起来这需要在启动Python之前设置:Changing LD_LIBRARY_PATH at runtime for ctypes
因此我建议使用包装器.sh
(如果您坚持使用.py
)脚本。另外,正如@chepner指出的那样,您可能需要考虑在标准位置(在virtualenv中)安装.so
文件。
答案 1 :(得分:6)
我对这个问题的解决方案是把它作为Python脚本的第一行(而不是通常的shebang):
exec env LD_LIBRARY_PATH=/some/path/to/lib /path/to/specific/python -x "$0" "$@"
这是如何运作的:
答案 2 :(得分:2)
Python,当获取环境变量的值时,如os.environ[‘LD_LIBRARY_PATH’]
或os.environ[‘PATH’]
,它将值从其父进程的环境复制到字典中,通常是bash(bash进程的环境得到了子进程,python运行实例)。
您可以使用bash的env
命令输出来查看此环境变量部分。
通过在修改任何环境变量后引入无限循环(/proc/<pid>/environ
),您还可以从while 1: pass
查看/读取此env数据。
如果你在python脚本中修改它之后从/proc/<pid>/environ
看到/读取这个变量值/数据,你会发现真实变量的数据没有得到修改,尽管python脚本显示修改过字典键值,已更新。
在os.environ['LD_LIBRARY_PATH']='/<new_location>'
中修改python脚本中的env变量时实际发生的是,它只是更新本地字典中的值,而不是映射到进程的env变量部分。因此,它不会一直传播以反映当前流程的环境,因为仅限本地词典被修改/更新/填充。
因此,如果我们想要反映新的环境变量,我们应该使用execv
用新的环境变量数据覆盖流程的内存映像。
示例:强>
new_lib = '/<new_location>'
if not new_lib in os.environ['LD_LIBRARY_PATH']:
os.environ['LD_LIBRARY_PATH'] += ':'+new_lib
try:
os.execv(sys.argv[0], sys.argv)
except Exception as e:
sys.exit('EXCEPTION: Failed to Execute under modified environment, '+e)
import xyz
#do something else
限制:理想情况下,python不应允许对os.environ
变量进行此类修改。
但由于没有常量字典数据类型,因此它允许修改数据变量。绝对没有修改值的用法,因为除非使用execv
,否则在运行进程的真实环境中没有任何用处。
答案 3 :(得分:1)
如果重新初始化环境,该解决方案将正常工作
import os
os.environ['LD_LIBRARY_PATH'] = os.getcwd() # or whatever path you want
代码必须放在适当的位置。...
os.execv(sys.argv[0], sys.argv)
答案 4 :(得分:1)
从coreutils 8.30开始,可以使用env -S
将shebang行拆分为单独的参数:
#!/usr/bin/env -S LD_LIBRARY_PATH=/path/to/lib python options
为了与旧系统兼容,您可以使用以下事实:shell允许所有命令都用引号引起来,而在python中,它只是字符串:
#!/bin/sh
"export" "LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH"
"exec" "python3" "$0" "$@"
# Further python program
import somemodule