简体   繁体   English

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

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

What I want我想要的是

So I'm using Visual Studio code and Python 3.7.0 and I'm just trying to import another python file, from another folder, into my python file .所以我正在使用 Visual Studio 代码和 Python 3.7.0,我只是想将另一个 python 文件从另一个文件夹导入到我的 python 文件中


Details细节

Here is my folder structure这是我的文件夹结构

root/
    dir1/
        data.txt
        task11.py
        task12.py
    dir2/
        data.txt
        task21.py
        task22.py
    Helpers/
        FileHelper/
            ReadHelper.py

So a short explanation:所以一个简短的解释:

  • I use the same function in every "task"-file我在每个“任务”文件中使用相同的功能
  • Instead of putting the function in every "task"-file, I've created a helper file where the function exists我没有将函数放在每个“任务”文件中,而是在该函数存在的地方创建了一个帮助文件
  • I want to import the helper file "ReadHelper.py" into my task files我想将帮助文件“ReadHelper.py”导入到我的任务文件中

What I've tried我试过的

eg in the file task11.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 *

None of the above solutions works as I always end up with the error: ModuleNotFoundError: No module named 'Helpers'上述解决方案均ModuleNotFoundError: No module named 'Helpers'因为我总是以错误ModuleNotFoundError: No module named 'Helpers'

I've also tried:我也试过:

  • from ..Helpers.FileHelper.ReadHelper import *

But it ends up with the error: ValueError: attempted relative import beyond top-level package但它最终出现错误: ValueError: attempted relative import beyond top-level package

So how can I import the file ReadHelper.py to my task files?那么如何将文件ReadHelper.py导入到我的任务文件中呢?


PS聚苯乙烯

There are some similar questions to this but they are really old and the answers have not helped me.有一些类似的问题,但它们真的很老,答案对我没有帮助。


Update 1更新 1

There is an option in Visual Studio code, Visual Studio 代码中有一个选项, vscode python 命令 If I run this command with this import from Helpers.FileHelper import ReadHelper then no errors are generated and the code executes perfectly.如果我使用这个 import from Helpers.FileHelper import ReadHelper运行此命令,则不会生成任何错误并且代码执行完美。

One downside is that this interactive window is slow at starting and it cannot handle inputs.一个缺点是此交互式窗口启动速度较慢,并且无法处理输入。

I tried the answer of @Omni as well:我也尝试了@Omni的答案:

$> python -m root.dir1.task11

And it worked!它奏效了! but as he said there is a downside, which is that it is slow to type in the terminal.但正如他所说,有一个缺点,就是在终端中输入很慢。

So I tried to create a task in Visual Studio Code that could execute the above shell command for the file that I'm currently is in, but did not succeed.因此,我尝试在 Visual Studio Code 中创建一个任务,该任务可以为我当前所在的文件执行上述 shell 命令,但没有成功。

Do you know how to crate a task in vscode to run the above command?你知道如何在 vscode 中创建一个任务来运行上面的命令吗?


I've also tried to add __init__.py -files under every directory so they would be seen as packages Python3 tutorial - 6.4 Module Packages .我还尝试在每个目录下添加__init__.py -files,以便将它们视为包Python3 教程 - 6.4 模块包 But this didn't help and the same error occurred.但这没有帮助,并且发生了同样的错误。


Update 2更新 2

I come up with a way to make it really easy to have a folder structure like this and get the imports to work correctly in the terminal.我想出了一种方法,让拥有这样的文件夹结构变得非常容易,并使导入在终端中正常工作。

Basically what I did was:基本上我所做的是:

  • created a pyhton script创建了一个pyhton脚本
  • created a task in visual studio code在 Visual Studio 代码中创建了一个任务

With this I can now run my python files, with the imports, by only pressing cmd + shift + B .有了这个,我现在可以通过导入运行我的 python 文件,只需按cmd + shift + B


Explanation解释

The visual studio task:视觉工作室任务:

{
    "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
            }
        }
    ]
}

The part that we want to focus on is this one:我们要关注的部分是:

"command": "python3 /PATH_TO_ROOT_FOLDER/run_python_file.py ${file}",

  • This part run the new python file I created at the root folder, and passes the path, of the file which is active, as a parameter这部分运行我在根文件夹中创建的新 python 文件,并将活动文件的路径作为参数传递

The python script:蟒蛇脚本:

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()
  • This python script gets as parameter the path to the active file这个python脚本获取活动文件的路径作为参数
  • Then it creates a shell command of the path (the shell command is like @kasper-keinänen 's answer)然后它创建路径的shell命令(shell命令就像@kasper-keinänen的答案)
  • Then it run that shell command然后它运行那个shell命令

With these modifications, I can run any file inside the root directory with imports from any file inside the root directory.通过这些修改,我可以运行根目录中的任何文件,并从根目录中的任何文件导入。

And I can do it by only pressing cmd + shift + B .我可以通过只按cmd + shift + B来做到这一点。

You could try running the script with the -m option that allows modules to be located using the Python module namespace docs.python.org .您可以尝试使用-m选项运行脚本,该选项允许使用 Python 模块命名空间docs.python.org来定位模块。

If you run the task11.py script then:如果您运行 task11.py 脚本,则:

$ python3 -m dir1.task11 

And in the task11.py do the import like:在 task11.py 中执行如下导入:

from Helpers.FileHelper.ReadHelper import *

If you're only trying to do this in VSCode, and not during normal run time.如果您只是想在 VSCode 中执行此操作,而不是在正常运行时执行此操作。 You can add the path in the .vscode/settings.json您可以在.vscode/settings.json添加路径

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

在此处输入图片说明

NOTE: This does not solve standard Python importing.注意:这不能解决标准的 Python 导入问题。 My use-case was specific to a monolithic project where all editor config files where in the root and thus I couldn't open 'webapp/' as a workspace itself.我的用例特定于一个整体项目,其中所有编辑器配置文件都位于根目录中,因此我无法将“webapp/”作为工作区本身打开。

Adding the full absolute path to the sys.path variable should make it work.将完整的绝对路径添加到sys.path变量应该使它工作。

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

from ReadHelper import *

a) Execute the task modules as scripts within an environment that knows about the helper functions. a) 在了解辅助函数的环境中将任务模块作为脚本执行。 That way the code in the taks modules does not have to know anything about the package structure present.这样,taks 模块中的代码就不必了解有关包结构的任何信息。 It imitates the builtins of the python interpreter.它模仿了 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) Use relative imports correctly. b) 正确使用相对导入。 In order to do so, you have to execute the task code via (this might be a disadvantage of this solution).为此,您必须通过执行任务代码(这可能是此解决方案的缺点)。

   $> python -m root.dir1.task11.task11

The problem is your file/folder structure.问题在于您的文件/文件夹结构。 I would suggest creating a sort of 'control' file in your root folder, which can then work from the top-down to reference all your other modules.我建议在您的根文件夹中创建一种“控制”文件,然后可以从上到下引用所有其他模块。

So let's say you had a file in your root folder called MasterTask.py it could look like this:因此,假设您的根文件夹中有一个名为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

One other option would be to move the Helpers folder into your Python37\\Lib\\site-packages folder, which would also allow the use of from Helpers.FileHelper.ReadHelper import * as is - assuming that you are not planning on this to be used on other machines other than your own.另一种选择是将 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