我如何告诉 pylint 变量将在 运行 时间定义?

How can I tell pylint that a variable will be defined at run time?

简略版:如果我在运行时定义一个装饰器来导入一个模块,并在func_globals中为一个方法声明它,如何我告诉 Pylint 结果变量已经定义了?

长版本:考虑以下示例:

from importlib import import_module

def with_import(module):
    modname = module.split('.')[-1]
    def decorate(func):
        def wrapper(*args, **kwargs):
            func.func_globals[modname] = import_module(module)
            return func(*args, **kwargs)
        return wrapper
    return decorate

@with_import('numpy')
def create_array(n):
    return numpy.empty(n)

print(create_array(5))

这段代码工作得很好,因为 with_import 装饰器为 create_array 函数声明了 numpy。但是,当我 运行 PyLint 时,我看到

E: 16,11: Undefined variable 'numpy' (undefined-variable)

有没有办法告诉 Pylint 这个变量实际上会在 运行 时定义?我真的不想禁用整个模块的 unused-variable 检查,以防有人在以后实际声明一个常规未使用的变量。

例如,您可以在块或行的基础上禁用检查

def f():
    # pylint: disable=E0602
    x[0] = 5
    y[0] = 5
# No errors

def f():
    x[0] = 5 # pylint: disable=E0602
    y[0] = 5
# Only y will raise the undefined variable error

对于装饰器,你有一个等同于第一个的装饰器,我真的很惊讶它的工作原理,并且认为它很丑陋但是:

@deco
# pylint: disable=E0602
def f():
    x[0] = 5 # No error here
y[0] = 5 # Error here

请注意,在 pylint 报告中会有一个 I: Locally disabling undefined-variable (E0602)

仅针对它发生的确切行禁用它:

@with_import('numpy')
def create_array(n):
    return numpy.empty(n) # pylint: disable=undefined-variable

如果您的装饰器将此类模块作为函数的参数提供怎么办?

这是一个工作示例:

from importlib import import_module

def with_import(module):
    modname = module.split('.')[-1]
    def decorate(func):
        def wrapper(*args, **kwargs):
            obj = import_module(module)
            func.func_globals[modname] = obj
            # merge modname=obj with kwargs
            return func(*args, **dict({modname: obj}, **kwargs))
        return wrapper
    return decorate

@with_import('numpy')
def create_array(n, numpy):
    # module available here and nobody complains
    return numpy.empty(n)

print create_array(5)

pylint关注typing.TYPE_CHECKING。所以你可以这样做:

import typing
if typing.TYPE_CHECKING:
    import numpy

@with_import('numpy')
def create_array(n):
    return numpy.empty(n)

typing.TYPE_CHECKING 在 运行 时始终为假,因此导入不会得到 运行。但是,pylint 假定 typing.TYPE_CHECKING 为真,并将分析代码,就好像已执行导入一样。