【问题标题】:How to correctly import a Python module in VS Code?如何在 VS Code 中正确导入 Python 模块?
【发布时间】:2020-04-29 07:36:21
【问题描述】:

我最近开始使用 Python 进行编程,并决定使用 Python 编写一些 Delphi 函数。我决定创建一个 Python 模块来保存我的函数。

现在,我尝试导入它,但在 Visual Studio Code 中出现此错误:

unable to import 'functions' pylint(import error) [5, 1]

这是我的代码:

import sys

sys.path.append('/Users/user123/Desktop/Python/Functions/')

import functions

这是一张图片:

【问题讨论】:

    标签: python-3.x visual-studio-code pylint


    【解决方案1】:

    鉴于您的文件/文件夹结构:

    ├── Functions
    │   └── functions.py
    ├── <main app folder>
    │   └── app.py
    

    尽管将 path/to/Functions 添加到 sys.path 后,您的导入可能会正确运行,但 Pylint 会向您发出警告,因为这不是推荐的导入方式,尤其是当您在外部导入模块时 应用程序包/文件夹。

    来自PEP8 Style Guide for Imports

    建议使用绝对导入,因为它们通常更具可读性 并且往往表现得更好(或至少给出更好的错误消息) 如果导入系统配置不正确(例如当一个 包内的目录最终位于sys.path):

    import mypkg.sibling 
    from mypkg import sibling 
    from mypkg.sibling import example
    

    推荐的解决方案是在setup Functions as a package下添加一个__init__.py文件:

    ├── parent
    │   └── Functions
    │       ├── __init__.py
    │       └── functions.py
    

    然后导入您的函数,如下所示:

    sys.path.append("/path/to/parent")
    
    # option 1
    from Functions import functions
    functions.copy()
    functions.delete()
    
    # option2
    from Functions.functions import copy, delete
    copy()
    delete()
    

    两个选项都应该正确运行并满足 PyLint。

    现在,如果你真的想像from functions import func 那样进行非绝对导入,并让 PyLint 接受它,我建议将 functions.py 重命名为其他名称。这是因为,在某些不区分大小写的系统上,导入 Functionsfunctions 可能会被视为同一个模块。当您告诉 PyLint 查看 /path/to/Functions(我稍后会展示)时,它可能无法区分 copydeleteFunctions 还是 functions 的一部分,它可能仍会显示导入错误。

    所以,你需要做的是重命名functions.py(例如filefuncs.py):

    ├── Functions
    │   └── filefuncs.py
    ├── <main app folder>
    │   └── app.py
    

    然后在您的 VS Code 工作区中,将其添加到您的 .vscode/settings.json 文件中,以告诉 PyLint 在哪里寻找 filefuncs 模块:

    "python.linting.pylintArgs": [
        "--init-hook",
        "import sys; sys.path.append('/path/to/Functions')"
    ]
    

    然后您现在可以像原始代码一样导入它,但不会出现 PyLint 错误:

    sys.path.append("/path/to/Functions")
    from filefuncs import copy, delete
    copy()
    delete()
    

    第二种方法可以满足您的需要,但它包含一些 PyLint 工作的变通方法。如果您可以使用我在开始时解释的推荐方式,请改用它。

    【讨论】:

      【解决方案2】:

      最简单的例子是:

      .
      ├── functions
      │   ├── functions.py
      └── main
          └── main.py
      

      现在在functions/functions.py 我有:

      from datetime import datetime
      
      def print_datetime():
          print(datetime.utcnow())
      

      main/main.py 我有:

      import sys
      sys.path.append(".")
      
      from functions.functions import print_datetime
      
      if __name__ == '__main__':
          print_datetime()
      

      这个sys.path.append(".") 正在帮助您从调用main.py 的位置切换上下文,更准确地说,它将更高的目录添加到python 模块路径。

      当您在项目的顶级目录中时,您现在可以运行main.py,这将产生如下结果:

      (venv) user@pc: .../59702230 
      $ python main/main.py 
      2020-01-12 09:51:01.469436
      

      有关如何执行此操作的更多详细信息,您可以阅读beyond top level package error in relative import 中的精彩 QA,其中包含有关如何使用不同方法解决相同问题的大量重要信息。

      希望对你有帮助!

      【讨论】:

      • 苦苦挣扎了好一阵子.....在 vs 代码中 ..sys.path.append(".") 帮助了我
      猜你喜欢
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 2020-01-10
      • 2021-03-31
      • 1970-01-01
      相关资源
      最近更新 更多