Python3 - 如何正确进行绝对导入并让Pylint满意

7
我在尝试理解Python 3的导入(我正在使用Python 3.5),但是遇到了很大的困难。这似乎是一个价值百万美元的问题,我知道它已经得到了各处的回答。但是我并没有真正理解应该如何完成;互联网上的答案差异很大。如果这几乎是重复的答案,那么我提前表示歉意。我非常感谢好的阅读材料的参考。
所以我有以下虚拟项目:
/my_project/main.py
/my_project/lib/__init__.py
/my project/lib/my_lib.py

如果可能的话,我想要做到以下几点:
  • 能够在当前工作目录下以python3 main.py的方式运行我的程序,其中my_project是当前工作目录。
  • 不修改任何时候的PYTHONPATH
  • 让pylint满意。
  • 使用正确的Python3导入。

main.py包含:

from .lib.my_lib import foo

if __name__ == '__main__':
    foo()

foo则是在lib/my_lib.py文件中定义的。

有了这个配置,我得到了以下错误:

SystemError: 父模块“”未加载,无法执行相对导入

我可以通过以下方式解决这个错误:

from lib.my_lib import foo

但是这不是 Python3 的绝对导入,对吧?而且 2)Pylint 报错:无法导入 'lib.my_lib' (import-error)

接下来我尝试添加 my_project/__init__.py 文件,并像下面这样导入:

from my_project.lib.my_lib import foo

在这种情况下,Pylint很开心,但我不能像这样运行:python3 main.pyImportError: No module named 'my_project' 那么我唯一能运行它的方式是从父目录作为模块运行:python3 -m my_project.main
那么我的问题是:是否有可能以正确的方式进行导入,同时仍然能够像这样执行:python3 main.py
非常感谢!

from lib.my_lib import foo 绝对导入:当前工作目录自动成为 sys.path 中的第一个目录。 - user707650
更加准确和正确地说:sys.path 中的第一个条目是 "包含用于调用 Python 解释器的脚本的目录" - user707650
我无法使用pylint重现此问题:我没有遇到导入错误。 - user707650
有一件事我忘了提到,那就是我在一个调用中运行pylint来检查多个文件,这些文件对应于其他项目。所以我有另一个my_project2my_project处于同一级别。它会不会搞乱路径,导致我在导入时出现错误?我不确定是否应该像这样运行pylint,还是逐个文件循环运行。 - user1011113
看起来我很难从我们的代码库中分离出问题并创建一个可重现的示例(其中包含许多其他内容)。在我找到更好的描述之前,我应该删除这个问题吗?我认为我应该开始询问如何在多个文件中使用Pylint;文档中没有写明,而且我在互联网上找到了争议性的答案。 - user1011113
显示剩余2条评论
1个回答

1
我会做这样的事情:

/path/README
/path/requirements.txt
/path/cleverappname/__main__.py
/path/cleverappname/__init__.py
/path/cleverappname/foo.py
/path/cleverappname/bar.py

假设你有类似于class CleverName(object)的东西在__init__.py中,以及像class Foo(object)这样的东西在foo.py中(对于bar也是一样的,你明白的)。

__main__中:

from cleverappname import CleverName
from cleverappname.foo import Foo
from cleverappname.bar import Bar

但是,它需要你将其作为Python使用,而不是脚本(这是正确的,因为它就是这样):python3 -m clevername Pylint似乎对此很满意。

1
我会使用相对导入来进行包内导入。以防万一有人决定重命名该包(或安装它的人决定重命名它)。 - user707650

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