当我使用os.chdir()从脚本获取包dir时,为什么我的命名空间导入不起作用?
例如,这是我的包结构来演示问题。
testpk/
testpk/bin
testpk/bin/runit.py
testpk/lib
testpk/lib/libcode.py
testpk/lib/__init__.py
这是我的lib代码,它只是打印已导入的
print "I've been imported"
runit.py的内容
#!/usr/bin/python
import sys, os
if __name__ == "__main__":
os.chdir('/home/moorepe/src/testpk')
print "working path = " , os.getcwd()
import lib.libcode
如果我运行runit,我会收到此错误:
moorepe@halifax$ bin/runit.py
Traceback (most recent call last):
File "bin/runit.py", line 6, in <module>
import lib.libcode
ImportError: No module named lib.libcode
然而,使用python命令行对其进行测试时,它按预期工作:
cd testpk
python -c "import lib.libcode
I've been imported
这可以从bin目录开始:
cd testpk/bin
python -c "import os; os.chdir('/home/moorepe/src/testpk') ; import lib.libcode"
I've been imported
任何人都可以解释出现了什么问题吗?
因此,除了PYTHONPATH之外,python使用当前dir作为路径。
所以这段代码通过添加sys.path.append(“。”)来工作,因为我强制当前工作的dir作为路径添加。
答案 0 :(得分:1)
如果您将当前目录的'.'
添加到sys.path
搜索文件夹列表,那么os.chdir()
将生效,import lib.libcode
应该开始工作:
档案 runit.py
:
#!/usr/bin/python
import sys, os
if __name__ == "__main__":
sys.path[0:0] = ['.'] # prefix current directory to list
os.chdir('/home/moorepe/src/testpk')
print "working path =", os.getcwd()
import lib.libcode
答案 1 :(得分:1)
这是我发现的另一种解决方案:
import sys
import os.path
sys.path.insert(1, os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') )
#from pprint import pprint as pp
#pp(sys.path)
import libcode
这样,您的顶级库名称看起来不像lib
,而是libcode
。
如果您正在创建python模块,则可能需要查看official documentation。他们建议使用__init__.py
以及与您的模块organizational structure匹配的目录结构(这似乎是“Pythonic”做事的方式)。虽然任何传统的 Ruby-ish 或 Java-ish lib
目录结构都可以正常工作,只要您了解模块加载路径并进行适当设置,以便您的模块是装载。
答案 2 :(得分:0)
您应确保testpk / lib /位于PYTHONPATH
。
sys.path.append('/path/to/testpk/lib/')
是确保您的包裹在PYTHONPATH
。
执行此操作的“正确方法”是将testpk
包及其所有子目录放在Python site-packages
目录中。
找出site-packages
(应该在PYTHONPATH
中)的位置。
GET_PYTHON_LIB_CMD="from distutils.sysconfig import get_python_lib; print (get_python_lib())"
python -c "$GET_PYTHON_LIB_CMD"
会给你这个位置。
答案 3 :(得分:0)
从给定的脚本中,如果要将库添加到相对于脚本本身的sys.path中,可以添加库计算脚本所在位置的位置,如下所示:
#!/usr/bin/env python
# testpk/bin/runit.py
import os
import sys
_op = os.path
# if file is referred to by symlink, make __file__ point to it's actual location
__file__ = _op.realpath(__file__)
# add __file__'s directory's parent directory to the path
sys.path.append(_op.abspath(_op.join(_op.dirname(__file__), "..")))
import lib
def main():
pass
if __name__ == "__main__":
main()
然后你可以从任何地方调用你的可执行文件:
% pwd
/tmp
% ./testpk/bin/runit.py
I've been imported
由于我在重新分配__file__
时考虑通过符号链接运行脚本,我甚至会这样做:
% pwd
/tmp
% ln -s ./testpk/bin/runit.py
% ./runit.py
I've been imported