解决动态加载模块的 Python linting 错误

问题描述 投票:0回答:1

考虑以下使用嵌套模块的项目结构:

$ tree
.
├── a
│   ├── b
│   │   ├── c
│   │   │   └── __init__.py
│   │   └── __init__.py
│   └── __init__.py
└── test.py

3 directories, 4 files

test.py
文件的内容:

from a.b.c import foo

print(foo())

a/b/c/__init__.py
的内容:

def foo():
    return "Hello world"

我想在导入东西时省略

b
并在
from a.c import foo
中使用
test.py
。这是因为我想在内部将代码组织在单独的子目录中,同时允许根目录中的文件使用相同的基本导入路径导入所有内容。我可以通过在
a/__init__.py
中添加以下代码来实现:

import importlib
import sys

importlib.import_module("a.b.c")
sys.modules["a.c"] = sys.modules["a.b.c"]

它有效,当我调用

python test.py
时,其中包含
from a.c import foo
我可以看到预期的
Hello world
输出。然而,各种 Python 工具和 linters 讨厌这个。如果我尝试在
pylint
上运行
test.py
,我可以看到它报告导入错误:

$ pylint test.py
************* Module test
test.py:1:0: C0114: Missing module docstring (missing-module-docstring)
test.py:1:0: E0401: Unable to import 'a.c' (import-error)
test.py:1:0: E0611: No name 'c' in module 'a' (no-name-in-module)

------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)

同样,如果我尝试在 PyCharm 中打开它,它会在导入行中报告错误:

Cannot find reference 'c' in '__init__.py' 
Unresolved reference 'foo' 

我怎样才能让这些工具理解我处理

c
模块的意图,就像它在
a
目录中一样?我知道我可以禁用各种 lint 放置评论,例如
# pylint: disable=E0401
test.py
但这不是可移植的(如果有人在一些不同的 IDE 中使用不同的 linter 怎么办......?)并隐藏问题而不是解决它。我也不想将这些复制到根目录中的每个
.py
文件中。

或者也许这是不可能实现的,我总是指定一个正确的完整路径......?

python pycharm python-import pylint
1个回答
0
投票

为什么不更改

__init__.py
中的
a
以导入所有必要的子模块并使其可访问。您可以根据以下
__init__.py
放置在
a
.

中的想法
import b.c as c

然后就可以访问

test.py
中的模块,如下:

import a
a.c.foo()

或者,您可以按照 ivvija 的建议在

c.py
中创建一个
a

c.py:

from b.c import *

为此,您只需要确保您没有在

__all__
中重新定义
a/b/c/__init__.py
并且如果您确保添加所有需要的功能,例如
__all__ = ["foo"]

© www.soinside.com 2019 - 2024. All rights reserved.