所以我正在使用Visual Studio代码和Python 3.7.0,并且我只是试图将另一个文件夹中的另一个python文件导入到我的python文件中。
这是我的文件夹结构
root/
dir1/
data.txt
task11.py
task12.py
dir2/
data.txt
task21.py
task22.py
Helpers/
FileHelper/
ReadHelper.py
例如在文件task11.py中:
from Helpers.FileHelper.ReadHelper import *
import os, sys
parentPath = os.path.abspath("../../")
if parentPath not in sys.path:
sys.path.insert(0, parentPath)
from Helpers.FileHelper.ReadHelper import *
import os, sys
sys.path.append('../../')
from Helpers.FileHelper.ReadHelper import *
以上解决方案均无效,因为我总是会遇到以下错误:
ModuleNotFoundError: No module named 'Helpers'
我也尝试过:
from ..Helpers.FileHelper.ReadHelper import *
但是最终出现错误:ValueError: attempted relative import beyond top-level package
那么如何将文件ReadHelper.py
导入任务文件?
有一些与此类似的问题,但它们确实很老,答案对我没有帮助。
Visual Studio代码中有一个选项,如果我使用此导入from Helpers.FileHelper import ReadHelper
运行此命令,则不会生成任何错误,并且代码可以完美执行。
一个缺点是该交互式窗口启动缓慢,无法处理输入。
我也尝试了@Omni的答案:
$> python -m root.dir1.task11
它奏效了!但是正如他所说的那样,它存在一个缺点,那就是输入终端的速度很慢。
因此,我尝试在Visual Studio Code中创建一个任务,该任务可以为我当前所在的文件执行上述shell命令,但未成功。
您知道如何在vscode中创建任务以运行上述命令吗?
我还尝试在每个目录下添加__init__.py
文件,以便将它们视为软件包Python3 tutorial - 6.4 Module Packages。但这没有帮助,并且发生了相同的错误。
我想出了一种方法,使拥有这样的文件夹结构非常容易,并使导入在终端中正常工作。
基本上我所做的是:
现在,我只需按cmd + shift + B
就可以运行带有导入的python文件。
Visual Studio任务:
{
"version": "2.0.0",
"tasks": [
{
"label": "Run python file",
"type": "shell",
"command": "python3 /PATH_TO_ROOT_FOLDER/run_python_file.py ${file}",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "new",
"focus": true
}
}
]
}
我们要关注的部分是这个:
"command": "python3 /PATH_TO_ROOT_FOLDER/run_python_file.py ${file}",
python脚本:
import os, sys
# This is a argument given trough a shell command
PATH_TO_MODULE_TO_RUN = sys.argv[1]
ROOT_FOLDER = "root/"
def run_module_gotten_from_shell():
# Here I take only the part of the path that is needed
relative_path_to_file = PATH_TO_MODULE_TO_RUN.split(ROOT_FOLDER)[1]
# Creating the shell command I want to run
shell_command = createShellCommand(relative_path_to_file)
os.system(shell_command)
# Returning "python3 -m PATH.TO.MODULE"
def createShellCommand(relative_path_to_file):
part1 = "python3"
part2 = "-m"
# Here I change the string "dir1/task11.py" => "dir1.task11"
part3 = relative_path_to_file.replace("/", ".")[:-3]
shell_command = "{:s} {:s} {:s}".format(part1, part2, part3)
return shell_command
run_module_gotten_from_shell()
通过这些修改,我可以运行根目录中的任何文件,并且可以从根目录中的任何文件导入。
我只需要按cmd + shift + B
就可以做到。
答案 0 :(得分:2)
您可以尝试使用-m
选项运行脚本,该选项允许使用Python模块命名空间docs.python.org定位模块。
如果您运行task11.py脚本,则:
$ python3 -m dir1.task11
然后在task11.py中执行如下导入:
from Helpers.FileHelper.ReadHelper import *
答案 1 :(得分:1)
a)在了解帮助程序功能的环境中,将任务模块作为脚本执行。这样一来,taks模块中的代码就不必了解有关当前包结构的任何信息。它模仿了python解释器的内置函数。
# cli argument #1 is the task module to execute
import sys
task_to_execute = sys.argv[1]
from Helpers.FileHelper.ReadHelper import *
exec(open(task_to_execute).read())
b)正确使用相对进口。为此,您必须通过执行任务代码(这可能是此解决方案的缺点)。
$> python -m root.dir1.task11.task11
答案 2 :(得分:1)
如果您只是想在 VSCode 中执行此操作,而不是在正常运行时执行此操作。您可以在 .vscode/settings.json
{
"python.analysis.extraPaths": [
"${workspaceFolder}/webapp"
],
}
注意:这不能解决标准的 Python 导入问题。我的用例特定于一个整体项目,其中所有编辑器配置文件都位于根目录中,因此我无法将“webapp/”作为工作区本身打开。
答案 3 :(得分:0)
将完整的绝对路径添加到sys.path
变量将使其起作用。
import sys
sys.path.append('/full/path/to/Helpers/FilesHelper/')
from ReadHelper import *
答案 4 :(得分:0)
问题在于您的文件/文件夹结构。我建议您在根文件夹中创建一种“控制”文件,然后可以从上至下使用它来引用所有其他模块。
因此,假设您的根文件夹中有一个名为MasterTask.py
的文件,它看起来像这样:
from dir1.task11.task11 import *
from dir1.task12.task12 import *
from dir2.task21.task21 import *
from dir2.task22.task22 import *
from Helpers.FileHelper.ReadHelper import *
class Master:
#Do your task work here
pass
另一种选择是将Helpers文件夹移动到Python37 \ Lib \ site-packages文件夹中,这也允许按原样使用from Helpers.FileHelper.ReadHelper import *
-假设您不打算使用此文件夹在您自己的机器以外的其他机器上。