从父文件夹导入模块
我正在运行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, inspect
replace第二行为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__)