让flake8区分未定义的函数和导入的星星

时间:2019-05-22 22:08:08

标签: python python-import pep8 flake8

我有一个相当大的项目,我试图在发布之前清理它,但是当我运行flake8时,我得到了很多

'F405 <function> may be undefined, or defined from star imports: generic_functions`

我可以通过替换以下行来避免这种情况:

from generic_functions import *

在文件的开头,但是:

  1. 我实际上使用了其中的所有函数,所以我不明白超过80个字符的限制来键入每个函数是多么的pythonic:

     from generic_functions import (function1, function2, function3, function4, function5, function6, function7...)
    
  2. 执行上述操作将很繁琐,尤其是当我需要在generic_functions.py

  3. 中的数十个函数中添加或删除时

另一个选择是禁用F405警告,但是如果该功能确实未定义怎么办?允许导入星星同时捕获任何未定义的东西将是很好的。有没有办法做到这一点?我尝试在导入行中添加#noqa,但似乎无济于事。

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

  1. 将导入内容保留为from generic_functions import *
  2. flake8 --ignore=F405 file.py的身份运行flake8。我真的不知道为什么# noqa无效,但是--ignore无效。
  3. 使用pylint测试其余可能的错误。 Pylint能够确定<function>已定义并导入了generic_functions

答案 1 :(得分:0)

您可以使用 pylint 来确定哪些功能是必需的,哪些不是。我写了一个函数来自动化这个过程。它的工作原理如下:

  1. 在脚本上运行 pylint 并匹配所有 W0614: Unused import 错误。
  2. 使用 vars() 获取目标模块中的变量列表
  3. 取那些集合的差异,只返回可以导入的东西。

import subprocess, types

def scrape_wildcard(filename, modvars):
    "Get variables imported from module in wild * import"
    error = "W0614: Unused import "
    unused = []
    for line in quickrun(['pylint', filename]):
        if error in line:
            unused.append(line.split(error)[1].split()[0])

    out = dict()
    for name in set(modvars.keys()) - set(unused):
        if not name.startswith('__'):
            func = modvars[name]
            if not isinstance(func, types.ModuleType):
                out[name] = modvars[name]
    return out


def quickrun(cmd, check=False, encoding='utf-8', errors='replace'):
    ret = subprocess.run(cmd, stdout=subprocess.PIPE, check=check)
    return ret.stdout.decode(encoding=encoding, errors=errors).splitlines()


import ????? as mymod
filename = "?????"
print('from', mymod.__name__, 'import', ', '.join(scrape_wildcard(filename, vars(mymod)).keys()))
'''

更换?????分别使用您的模块名称和模块的文件名。