简短版本:如果我定义一个装饰器在运行时导入模块并在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
检查,以防有人实际在以后声明一个常规的未使用变量。
答案 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)