我运行的是Python 2.5。

这是我的文件夹树:

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

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

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

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


当前回答

这个问题似乎与模块位于父目录或类似的内容无关。

您需要将包含ptdraft的目录添加到PYTHONPATH

您说导入nib与您一起工作,这可能意味着您将ptdraft本身(而不是其父)添加到PYTHONPATH。

其他回答

你可以使用相对导入(python >= 2.5):

from ... import nib

(Python 2.5新增功能)PEP 328:绝对和相对导入

编辑:增加了另一个点。“去送两个包裹

我们的文件夹结构:

/myproject
  project_using_ptdraft/
    main.py
  ptdraft/
    __init__.py
    nib.py
    simulations/
      __init__.py
      life/
        __init__.py
        life.py

我理解这一点的方式是以包为中心的观点。 包根是ptdraft,因为它是包含__init__.py的最顶层

例如,包中的所有文件都可以使用绝对路径(相对于包根)进行导入 在life.py中,我们简单地有:

import ptdraft.nib

然而,为了包开发/测试目的而运行life.py,而不是python life.py,我们需要使用:

cd /myproject
python -m ptdraft.simulations.life.life

注意,在这一点上,我们根本不需要修改任何路径。


更令人困惑的是,当我们完成ptdraft包时,我们想在一个驱动程序脚本中使用它,它必须在ptdraft包文件夹之外,也就是project_using_ptdraft/main.py,我们需要摆弄路径:

import sys
sys.path.append("/myproject")  # folder that contains ptdraft
import ptdraft
import ptdraft.simulations

使用python main.py运行脚本没有问题。

有用的链接:

https://tenthousandmeters.com/blog/python-behind-the-scenes-11-how-the-python-import-system-works/(查看如何使用__init__.py) https://chrisyeh96.github.io/2017/08/08/definitive-guide-python-imports.html#running-package-initialization-code https://stackoverflow.com/a/50392363/2202107 https://stackoverflow.com/a/27876800/2202107

相对进口(如从..Import mymodule)只在包中工作。 导入当前模块父目录中的'mymodule':

import os
import sys
import inspect

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

import mymodule

编辑:__file__属性并不总是给定的。我现在建议使用inspect模块来检索当前文件的文件名(和路径),而不是使用os.path.abspath(__file__)

与过去的答案风格相同,但行数更少:P

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

文件返回您正在工作的位置

不太懂python 2。 在python 3中,父文件夹可以按如下方式添加:

import sys 
sys.path.append('..')

...然后我们可以从中导入模块