如何在VS Code中正确导入Python模块?

14

我最近开始用Python编程,决定将一些Delphi函数用Python编写。我决定创建一个包含我的函数的单一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

这里是一张图片:

https://istack.dev59.com/5EGbk.webp

2个回答

17

考虑到您的文件/文件夹结构:

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

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

来自PEP8 Style Guide for Imports

Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path):

import mypkg.sibling 
from mypkg import sibling 
from mypkg.sibling import example
建议的解决方案是通过在Functions下添加一个__init__.py文件,将其设置为一个包:setup Functions as a package
├── 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时(稍后会展示),它可能无法区分copydelete是属于Functions还是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 的解决方法。如果你能使用我在开头解释的推荐方法,那么请使用它。

4

最简单的例子如下:

.
├── 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中阅读一篇很棒的问答。这里有许多有关如何使用不同方法解决相同问题的重要信息。

希望这会对您有所帮助!


已经苦苦挣扎了一段时间......在 VS Code 中,sys.path.append(".") 帮助了我。 - TechDog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接