1

当我使用 os.chdir() 从脚本获取包目录时,为什么我的命名空间导入不起作用?

例如这里是我的包结构来演示这个问题。

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

谁能解释出了什么问题?

所以这不起作用的原因是python使用当前目录作为除了PYTHONPATH之外的路径。

所以这段代码通过添加 sys.path.append(".") 来工作,因为我强制当前工作目录作为路径添加。

4

4 回答 4

1

如果将'.'当前目录的 a 添加到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
于 2012-11-04T17:24:14.820 回答
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.

“官方”(Pythonic)方式

如果您正在创建一个 python 模块,您可能需要查看官方文档。他们建议使用__init__.py与模块的 组织结构相匹配的目录结构(这似乎是“Pythonic”的做事方式)。尽管任何传统的 Ruby-ishJava-ish lib目录结构都是可行的,只要您了解模块加载路径并适当设置它以使您的模块可加载。

于 2014-09-24T18:39:52.617 回答
0

您应该确保 testpk/lib/ 在您的PYTHONPATH.

sys.path.append('/path/to/testpk/lib/') 

是确保您的包裹在您的PYTHONPATH.

这样做的“正确方法”是将您的testpk包及其所有子目录放在您的 Pythonsite-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" 

会给你位置。

于 2012-11-04T16:14:20.657 回答
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
于 2012-11-04T16:42:36.577 回答