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

时间:2017-02-14 16:05:12

标签: python python-decorators pylint

简短版本:如果我定义一个装饰器在运行时导入模块并在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装饰器为numpy函数声明了create_array。但是,当我运行PyLint时,我看到了

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

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

4 个答案:

答案 0 :(得分:2)

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 在运行时始终为 false,因此不会运行导入。但是,pylint 假设 typing.TYPE_CHECKING 为真,并且会像执行导入一样分析代码。

答案 1 :(得分:1)

您可以基于块或行禁用检查,例如

if role == Qt.EditRole: 
        value = self.components[row]
        return value

对于装饰器,你有一个与第一个相同的东西,我实际上很惊讶它有效,并认为它很难看但是:

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

请注意,您在pylint报告中会有@deco # pylint: disable=E0602 def f(): x[0] = 5 # No error here y[0] = 5 # Error here

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

如果你的装饰者为你的功能提供参数模块怎么办?

这是一个有效的例子:

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)