从父文件夹导入模块
我正在运行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? ”,这里是一个简短的,简单的,希望易于理解的答案。 它应该与不同的操作系统交叉兼容 ,因为模块os , sys和inspect是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__)