我运行的是Python 2.5。

这是我的文件夹树:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(我在每个文件夹中都有__init__.py,为了可读性,这里省略了)

我如何从生命模块内导入nib模块?我希望不需要修改sys.path就可以做到。

注意:正在运行的主模块在ptdraft文件夹中。


当前回答

虽然这是违反所有规则的,但我还是想提一下这种可能性:

您可以先将文件从父目录复制到子目录。接下来导入它,然后删除复制的文件:

例如,在life.py中:

import os
import shutil

shutil.copy('../nib.py', '.')
import nib
os.remove('nib.py')

# now you can use it just fine:
nib.foo()

当然,当nibs尝试使用相对导入/路径导入/读取其他文件时,可能会出现一些问题。

其他回答

下面是一个更通用的解决方案,它将父目录包含到sys. conf中。路径(适用于我):

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

虽然这是违反所有规则的,但我还是想提一下这种可能性:

您可以先将文件从父目录复制到子目录。接下来导入它,然后删除复制的文件:

例如,在life.py中:

import os
import shutil

shutil.copy('../nib.py', '.')
import nib
os.remove('nib.py')

# now you can use it just fine:
nib.foo()

当然,当nibs尝试使用相对导入/路径导入/读取其他文件时,可能会出现一些问题。

我有一个问题,我必须导入一个Flask应用程序,它有一个导入,也需要在单独的文件夹中导入文件。这部分使用了Remi的答案,但假设我们有一个像这样的存储库:

.
└── service
    └── misc
        └── categories.csv
    └── test
        └── app_test.py
    app.py
    pipeline.py

然后,在从app.py文件导入app对象之前,我们将目录向上更改一层,因此当我们导入app(它导入了pipeline.py)时,我们也可以读入其他文件,如csv文件。

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir)

os.chdir('../')
from app import app

在导入Flask应用程序之后,你可以使用os.chdir('./test'),这样你的工作目录就不会被改变。

我有一个专门针对git存储库的解决方案。

首先,我使用sys.path.append('..')和类似的解决方案。如果你导入的文件本身使用sys.path.append('..')导入文件,这会导致特别的问题。

然后我决定总是附加git存储库的根目录。在一行中是这样的:

sys.path.append(git.Repo('.', search_parent_directories=True).working_tree_dir)

或者更详细一点,像这样:

import os
import sys
import git
def get_main_git_root(path):
    main_repo_root_dir = git.Repo(path, search_parent_directories=True).working_tree_dir
    return main_repo_root_dir
main_repo_root_dir = get_main_git_root('.')
sys.path.append(main_repo_root_dir)

对于最初的问题:根据存储库的根目录,导入将是

import ptdraft.nib

or

import nib

对我来说,访问父目录的最短和我最喜欢的联机程序是:

sys.path.append(os.path.dirname(os.getcwd()))

or:

sys.path.insert(1, os.path.dirname(os.getcwd()))

Os.getcwd()返回当前工作目录的名称,os.path.dirname(directory_name)返回传入目录的目录名称。

实际上,在我看来,Python项目架构应该是这样的:子目录中的任何模块都不会使用父目录中的任何模块。如果发生了这样的事情,就值得重新考虑项目树。

另一种方法是将父目录添加到PYTHONPATH系统环境变量。