0
  • 我正在为日常工作编写一组python 脚本
  • 为了避免重复,我们想利用import来分享一些工具。
  • 为了保留repository maintainable,我们有子文件夹来收集用于特定目的的脚本,并lib-folder在每个子文件夹中保留共享功能。

结构看起来像这样。

root
├── lib
│   ├── hello.py
└── sub
    ├── hello_user.py
    └── lib

__init__.py files exist, but are filtered for better readability

hello_user.py 中的代码是这样的:

from lib.hello import hello
hello()

在 hello.py 中:

def hello():
    print("Hello")
  • PYTHONPATH设置为root folder.
  • 当我尝试执行“python sub/hello_user.py”时,出现错误“ImportError: No module named hello”。如果我将 sub/lib 重命名为 sub/lib_hide,我会得到预期的输出“Hello”。
  • 如何让 python 从root/lib而不是root/sub/lib导入?
  • 设置PYTHONPATH to "root/.."并且importing "root.lib"可以工作,但可能不是一个可行的选项(需要使用脚本和所有现有脚本对所有设置进行更改)。
  • 我更喜欢只修改import statement. 相对路径会很好,但是我如何将 a 命名relative path为父文件夹?“..”。lib.hello不起作用。
4

2 回答 2

1

如果使用 执行脚本python sub/hello_user.py,则目录sub将自动添加sys.path为第一个元素。因此root/sub/lib会发现之前root/lib并因此隐藏它,无论在哪里PYTHONPATH点。改变这一点的唯一方法是确保root出现root/sub在路径之前:

sys.path.insert(0, '.../root')

如果你导入模块(或直接使用执行模块python -m sub.hello_user),那么情况就不同了。

在 python2 中,导入被隐式视为相对,因此它会尝试导入root/sub/lib/hello.pyroot/lib再次被root/sub/lib.

Python3 通过默认导入绝对来解决这个问题,所以它会 import root/lib/hello.py. 您可以通过添加以下内容在 python2 中获得此行为from __future__ import absolute_import

# root/sub/hello_user.py:

from __future__ import absolute_import
from lib import hello      # imports root/lib/hello.py
from sub.lib import hello  # imports root/sub/lib/hello.py
from .lib import hello     # same, but relative import instead of absolute

但是,这仍然只有sub在之前不在路径中时才有效root

于 2013-07-31T08:06:50.770 回答
0

您应该尝试将您的 roor/lib 文件夹插入到 sys.path:

import sys
sys.path.insert(1, 'complete/path/root/lib')

sys.path 是“指定模块搜索路径的字符串列表。从环境变量 PYTHONPATH 初始化,加上依赖于安装的默认值”(来自http://docs.python.org/2/library/sys.html ?highlight=sys.path#sys.path)。

两条评论:建议保持 sys.path[0] 不变(因此为 1),因为第一个 (0) 是当前文件夹是预期的行为。其次,有 sys.path.append 它将所需的路径添加到 sys.path 的末尾(不是你想要的)。

还有可能有用的 imp lib ray ( http://docs.python.org/2/library/imp )。

希望有帮助,P

于 2013-07-31T07:49:14.227 回答