我运行的是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文件夹中。
当前回答
如果将模块文件夹添加到PYTHONPATH中失败,则可以修改sys. conf文件。Python解释器在你的程序中搜索要导入的模块的路径列表,Python文档说:
When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations: the directory containing the input script (or the current directory). PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH). the installation-dependent default. After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended.
知道了这一点,你可以在程序中执行以下操作:
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
其他回答
这个问题似乎与模块位于父目录或类似的内容无关。
您需要将包含ptdraft的目录添加到PYTHONPATH
您说导入nib与您一起工作,这可能意味着您将ptdraft本身(而不是其父)添加到PYTHONPATH。
上面提到的解决方案也很好。这个问题的另一个解决方案是
如果你想从顶级目录导入任何东西。然后,
from ...module_name import *
此外,如果您想从父目录导入任何模块。然后,
from ..module_name import *
此外,如果您想从父目录导入任何模块。然后,
from ...module_name.another_module import *
通过这种方式,如果您愿意,您可以导入任何特定的方法。
在删除了一些系统路径黑客后,我认为添加它可能是有价值的
我喜欢的解决方案。
注意:这是一个框架挑战-没有必要在代码中做。
假设有一棵树,
project
└── pkg
└── test.py
test.py包含什么
import sys, json; print(json.dumps(sys.path, indent=2))
使用路径执行只包括包目录
python pkg/test.py
[
"/project/pkg",
...
]
但是使用module参数会包含项目目录
python -m pkg.test
[
"/project",
...
]
现在,从项目目录导入的所有内容都可以是绝对的。不需要再耍花招了。
这是对我来说最简单的解决方法:
from ptdraft import nib
这里有一个简单的答案,你可以看到它是如何工作的,小而跨平台。 它只使用内置模块(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__'没有定义