我运行的是Python 2.5。
这是我的文件夹树:
ptdraft/
nib.py
simulations/
life/
life.py
(我在每个文件夹中都有__init__.py,为了可读性,这里省略了)
我如何从生命模块内导入nib模块?我希望不需要修改sys.path就可以做到。
注意:正在运行的主模块在ptdraft文件夹中。
我运行的是Python 2.5。
这是我的文件夹树:
ptdraft/
nib.py
simulations/
life/
life.py
(我在每个文件夹中都有__init__.py,为了可读性,这里省略了)
我如何从生命模块内导入nib模块?我希望不需要修改sys.path就可以做到。
注意:正在运行的主模块在ptdraft文件夹中。
当前回答
虽然原作者可能不再寻找解决方案,但为了完整,有一个简单的解决方案。它是像这样运行life.py模块:
cd ptdraft
python -m simulations.life.life
通过这种方式,您可以从nib.py导入任何东西,因为ptdraft目录在路径中。
其他回答
与过去的答案风格相同,但行数更少:P
import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)
文件返回您正在工作的位置
pathlib库(包含在>= Python 3.4中)使得将父目录的路径附加到PYTHONPATH非常简洁和直观:
import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))
相对进口(如从..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__)
这里有一个简单的答案,你可以看到它是如何工作的,小而跨平台。 它只使用内置模块(os, sys和inspect),所以应该工作 因为Python就是为此而设计的。
更短的代码回答-更少的行和变量
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 the module name.
sys.path.pop(0)
如果行数少于这个数,请将第二行替换为import os。Path为Path, sys, inspect, 添加检查。在getsourcefile的开头(第3行)并删除第一行。 -然而,这会导入所有的模块,因此可能需要更多的时间,内存和资源。
我的答案代码(长版本)
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 # Replace "my_module" here with the module name.
它使用了一个例子,从堆栈溢出回答如何获得当前的路径 在Python中执行文件?使用内置工具查找正在运行的代码的源(文件名)。
从inspect import getsourcefile 从操作系统。路径导入 接下来,无论你想从哪里找到源文件,你只需使用: abspath (getsourcefile(λ:0))
我的代码添加了一个文件路径到sys。Path, python路径列表 因为这允许Python从该文件夹导入模块。
在代码中导入模块后,在新行上运行sys.path.pop(0)是个好主意 当添加的文件夹具有与导入的另一个模块同名的模块时 稍后在节目中。您需要删除导入前添加的列表项,而不是其他路径。 如果您的程序没有导入其他模块,则不删除文件路径是安全的,因为 在程序结束后(或重新启动Python shell),对sys. exe所做的任何编辑。路径消失。
关于文件名变量的说明
我的回答没有使用__file__变量来获取运行的文件路径/文件名 代码,因为这里的用户经常描述它不可靠。你不应该用它 用于从其他人使用的程序的父文件夹中导入模块。
以下是一些行不通的例子(引用自这个Stack Overflow问题):
•它在某些平台上找不到•它有时不是完整的文件路径
Py2exe没有__file__属性,但有一个变通方法 当你使用execute()从IDLE运行时,没有__file__属性 OS X 10.6哪里我得到NameError:全局名称'__file__'没有定义
我有一个问题,我必须导入一个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'),这样你的工作目录就不会被改变。