簡體   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