从父文件夹导入模块

我正在运行Python 2.5。

这是我的文件夹树:

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

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

如何从life模块内部导入nib模块? 我希望有可能没有修补与sys.path。

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

这似乎是问题是不是有关的模块是在父目录或类似的东西。

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

你说import nib和你一起工作,这可能意味着你把ptdraft本身(不是它的父类)加到了PYTHONPATH中。

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

 from ... import nib 

(Python 2.5中的新function)PEP 328:绝对和相对导入

编辑 :添加另一个点'。 去两个包

相对导入(如from .. import mymodule )只能在包中使用。 要导入当前模块父目录中的“mymodule”:

 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) import mymodule 

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

如果将模块文件夹添加到PYTHONPATH中不起作用,则可以修改程序中的sys.path列表,Python解释器search要导入的模块, python文档说:

当导入一个名为spam的模块时,解释器首先search具有该名称的内置模块。 如果没有find,它在variablessys.path给出的目录列表中search一个名为spam.py的文件。 sys.path从这些位置初始化:

  • 包含input脚本(或当前目录)的目录。
  • PYTHONPATH(目录名称列表,与shellvariablesPATH语法相同)。
  • 安装相关的默认值。

初始化后,Python程序可以修改sys.path 。 包含正在运行的脚本的目录放置在searchpath的开头,位于标准库path之前。 这意味着该目录中的脚本将被加载,而不是在库目录中具有相同名称的模块。 这是一个错误,除非有意更换。

知道这一点,你可以在你的程序中做到以下几点:

 import sys # Add the ptdraft folder path to the sys.path list sys.path.append('/path/to/ptdraft/') # Now you can import your module from ptdraft import nib # Or just import ptdraft 

您可以在sys.path中列出的“模块searchpath”中使用OS依赖path。 所以你可以很容易地添加如下所示的父目录

 import sys sys.path.insert(0,'..') 

如果你想添加父母目录,

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

这是更通用的解决scheme,包括父目录到sys.path(适用于我):

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

使用来自Stack Overflow的答案“ 如何获得Python中当前执行文件的path? ”,这里是一个简短的,简单的,希望易于理解的答案。 它应该与不同的操作系统交叉兼容 ,因为模块ossysinspect是Python的一部分(它是为许多操作系统构build的,所以它们被devise为)。

 from inspect import getsourcefile from os.path import abspath 

接下来,无论你想从你那里find源文件,只要使用:

 abspath(getsourcefile(lambda:0)) 

此外,我的答案不使用__file__variables,因为Stackoverflow用户经常提到它可能是不可靠的 ,并不适用于每个操作系统 – 它并不总是可用的, 并不总是包含完整的文件path 。 当然你可以在自己的代码中使用__file__ ,如果你不关心引起的问题或者想要less一点的代码。
从这个问题这个常见的方法引用的一些问题如何获得Python中当前执行文件的path? :

  • py2exe没有__file__属性,但有一个解决方法
  • 当你使用execute()从IDLE运行时,没有__file__属性
  • OS X 10.6我得到的NameError: global name '__file__' is not defined

所以我的答案不是缩短的,是:

 from inspect import getsourcefile import os.path import sys current_path = os.path.abspath(getsourcefile(lambda:0)) current_dir = os.path.dirname(current_path) parent_dir = current_dir[:current_dir.rfind(os.path.sep)] sys.path.insert(0, parent_dir) import my_module # Change name here to your module! 

避免用导入的模块的文件path填充 sys.path pythonpath列表 ,我build议在新行上添加代码sys.path.pop(0)到上面的代码。 确保删除的path是在模块导入之前添加的相同项目,所以不会意外删除其他path。 添加的目录包含与程序中稍后导入的另一个模块同名的模块 ,此代码是最重要的。
可以不改变它,因为我发现在程序中对sys.path所做的任何编辑都不是永久的,并且在重新启动Pythonshell之后,添加的新模块位置将从sys.path消失。

我的答案可以缩短,所以这里是:

 from inspect import getsourcefile import os.path as path, sys current_dir = path.dirname(path.abspath(getsourcefile(lambda:0))) sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)]) import my_module # Replace "my_module" here with your module's name. sys.path.pop(0) 

如果你想要更多的最小代码,你可以删除第一行,用import os.path as path, sys, inspectreplace第二行为import os.path as path, sys, inspect然后import os.path as path, sys, inspect前缀getsourcefile inspect. ,但是这将导入整个 inspect模块,所以可能需要更多的时间,内存和资源。

不太了解python 2。
在python 3中,父文件夹可以添加如下:

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

…然后可以从中导入模块

当不在包含__init__.py文件的包环境中时,pathlib库(包含在> = Python 3.4中)使得将父目录的path追加到PYTHONPATH中非常简洁直观:

 import sys from pathlib import Path sys.path.append(str(Path('.').absolute().parent)) 

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

与过去的答案一样的风格 – 但less了几行:P

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

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

与图书馆合作。 创build一个名为nib的库,使用setup.py安装它,让它驻留在站点包中,并解决您的问题。 你不需要把你制作的所有东西放在一个包里。 把它分解成碎片。

在Linux系统中,您可以创build一个从“life”文件夹到nib.py文件的软链接。 那么,你可以简单地导入它,如:

 import nib 

你可以追加你的目录path到sys

 import sys import os sys.path.append(os.path.__file__)