Python——从不是包的目录中导入模块

15

我有这样的一个目录结构...

dir/
  build.py
dir2
  dir3/
  packages.py
现在,需要build.py使用packages.py--请注意,dir2不是一个包。
那么,如何最好地将packages.py加载到build.py中(目录结构不能更改)?
编辑:看起来sys.path.append的解决方案很好--但有一件事--我需要很少使用packages.py文件--并保持包括一个罕见使用的目录的sys.path却排在前面--这是最好的选择吗?
编辑II:我认为imp的解决方案是最好的。
import imp    
packages = imp.load_source('packages', '/path/to/packages.py')

编辑 III

针对Python 3.x

请注意,imp.load_source和一些其他函数已经被弃用。所以今天你应该使用imp.load_module

fp, pathname, description = imp.find_module('packages', '/path/to/packages.py')
try:
    mod = imp.load_module('packages', fp, pathname, description)
finally:
    # since we may exit via an exception, close fp explicitly
    if fp:
        fp.close()

1
最好的选择是将其制作成一个包。你真的不能做到吗? - Gareth Latty
不行。因为在 dir2 中,除了 packages.py 外,其他文件都不是 Python 文件。 packages.py 仅包含一些 build.py 的配置信息。 - treecoder
你有没有考虑使用不同的格式来存储配置文件?如果你的配置文件不需要包含代码,为什么不将其存储为 JSON 或其他类似的格式呢?这样就不需要导入它了。此外,你可以在 Python 包中拥有其他文件,我真的不明白为什么会成为问题。 - Gareth Latty
关于其他格式——我认为在我的情况下,Python配置文件比任何其他格式更适合和灵活。 - treecoder
1
@good_computer,find_module和load_module也已经过时了,将来整个imp模块可能都会被弃用,如果可能的话,您应该使用importlib来替换它。 - freeforall tousez
2个回答

10

你可以这样做:

sys.path.append('./dir2/dir3')
import packages

或者更好的方案:

sys.path.append(os.path.join(os.path.dirname(__file__), 'dir2/dir3'))
import packages

或(来源于此处:如何按完整路径导入模块?

import imp    
packages = imp.load_source('packages', '/path/to/packages.py')

1
有没有“唯一正确”的方法是第三种?-避免直接干扰sys.path - Mr_and_Mrs_D

6

在IT技术领域,有一种做法是推荐的,那就是第三种——避免直接操作sys.path,这样更为稳妥。

我也遇到了同样的问题,但我已经解决了它。

dir/
  build.py
dir2
  dir3/
    packages.py
  1. 将文件__init__.py添加到dir1, dir2, dir3 ...中。
  2. 在包层次结构内,使用两个点

build.py想要导入packages.py,在build.py中编写:

import ..dir2.dir3.packages
from ..dir2.dir3.packages import function

https://docs.python.org/2/whatsnew/2.5.html#pep-328-absolute-and-relative-imports

从父文件夹导入模块

如何导入位于上级目录的Python类?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接