繁体   English   中英

从另一个不是子文件夹的文件夹中导入 python 文件

[英]Import python file from another folder that is not a child

我想要的是

所以我正在使用 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

所以一个简短的解释:

  • 我在每个“任务”文件中使用相同的功能
  • 我没有将函数放在每个“任务”文件中,而是在该函数存在的地方创建了一个帮助文件
  • 我想将帮助文件“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'因为我总是以错误ModuleNotFoundError: No module named 'Helpers'

我也试过:

  • from ..Helpers.FileHelper.ReadHelper import *

但它最终出现错误: ValueError: attempted relative import beyond top-level package

那么如何将文件ReadHelper.py导入到我的任务文件中呢?


聚苯乙烯

有一些类似的问题,但它们真的很老,答案对我没有帮助。


更新 1

Visual Studio 代码中有一个选项, vscode python 命令 如果我使用这个 import from Helpers.FileHelper import ReadHelper运行此命令,则不会生成任何错误并且代码执行完美。

一个缺点是此交互式窗口启动速度较慢,并且无法处理输入。

我也尝试了@Omni的答案:

$> python -m root.dir1.task11

它奏效了! 但正如他所说,有一个缺点,就是在终端中输入很慢。

因此,我尝试在 Visual Studio Code 中创建一个任务,该任务可以为我当前所在的文件执行上述 shell 命令,但没有成功。

你知道如何在 vscode 中创建一个任务来运行上面的命令吗?


我还尝试在每个目录下添加__init__.py -files,以便将它们视为包Python3 教程 - 6.4 模块包 但这没有帮助,并且发生了同样的错误。


更新 2

我想出了一种方法,让拥有这样的文件夹结构变得非常容易,并使导入在终端中正常工作。

基本上我所做的是:

  • 创建了一个pyhton脚本
  • 在 Visual Studio 代码中创建了一个任务

有了这个,我现在可以通过导入运行我的 python 文件,只需按cmd + shift + B


解释

视觉工作室任务:

{
    "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()
  • 这个python脚本获取活动文件的路径作为参数
  • 然后它创建路径的shell命令(shell命令就像@kasper-keinänen的答案)
  • 然后它运行那个shell命令

通过这些修改,我可以运行根目录中的任何文件,并从根目录中的任何文件导入。

我可以通过只按cmd + shift + B来做到这一点。

您可以尝试使用-m选项运行脚本,该选项允许使用 Python 模块命名空间docs.python.org来定位模块。

如果您运行 task11.py 脚本,则:

$ python3 -m dir1.task11 

在 task11.py 中执行如下导入:

from Helpers.FileHelper.ReadHelper import *

如果您只是想在 VSCode 中执行此操作,而不是在正常运行时执行此操作。 您可以在.vscode/settings.json添加路径

{
    "python.analysis.extraPaths": [
        "${workspaceFolder}/webapp"
    ],
}

在此处输入图片说明

注意:这不能解决标准的 Python 导入问题。 我的用例特定于一个整体项目,其中所有编辑器配置文件都位于根目录中,因此我无法将“webapp/”作为工作区本身打开。

将完整的绝对路径添加到sys.path变量应该使它工作。

import sys
sys.path.append('/full/path/to/Helpers/FilesHelper/')

from ReadHelper import *

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

问题在于您的文件/文件夹结构。 我建议在您的根文件夹中创建一种“控制”文件,然后可以从上到下引用所有其他模块。

因此,假设您的根文件夹中有一个名为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 *使用from Helpers.FileHelper.ReadHelper import * - 假设您不打算使用它在您自己以外的其他机器上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM