【问题标题】:VSCode, Python3.7: pylint no-member error with custom decorated classVSCode,Python3.7:自定义装饰类的 pylint 无成员错误
【发布时间】:2020-11-11 14:12:17
【问题描述】:

我最近将一个实例方法从其类定义中移出,并将其作为一个全局函数(例如:deco_function),以便能够再次在不同的类中使用它。详细解释和bug复现见以下代码:

def deco_function(cls):
    
    def inner_fct(self):
        print('do something')

    cls.deco_function = inner_fct
    return cls

@deco_function
class Something:

    def __init__(self):
        print('init')
        self.deco_function()
        print('done')

if __name__ == '__main__':
    a = Something()

代码运行良好,正在打印

init
do something
done

然而,VSCode 将self.deco_function() 红色下划线,并用 pylint 说明,Instance 'Something' 没有 'deco_function' 成员。

有没有办法阻止 pylint 标记它或让 VSCode 将 deco_function 识别为实例成员?

感谢您的建议。

【问题讨论】:

    标签: python-3.x visual-studio-code pylint


    【解决方案1】:

    您必须使用 PyLint 插件来判断哪些类成员是运行时生成的

    在您的 PYTHONPATH 上的某处创建一个文件 pylint_decorator.py

    import astroid
    from astroid import MANAGER
    
    def register(linter):
      # Needed for registering the plugin.
      pass
    
    def transform(cls):
      if not cls.decorators: return
      if any(map(lambda x: x.name == 'deco_function', cls.decorators.nodes)):
        extension_module = astroid.parse("""
    def deco_function(self):
      pass
    """)
        for name, objs in extension_module.locals.items():
          cls.locals[name] = objs
    
    MANAGER.register_transform(astroid.ClassDef, transform)
    

    然后使用以下设置配置 VSC

    "python.linting.pylintArgs": ["--load-plugins", "pylint_decorator"]
    

    这仅在您使用 @deco_function 语法时有效。

    如果调用装饰器函数 PyLint 将看不到装饰器的使用

    # this use will not be catched by the plugin
    class Something:
        def __init__(self):
            print('init')
            self.deco_function()
            print('done')
    Something = deco_function(Something)
    

    【讨论】:

    • 似乎还有另一个缺陷:<class 'UnboundLocalError'>: local variable 'extension_module' referenced before assignmentpylint(astroid-error) 知道吗?该错误现在出现在我打开的任何模块中......
    • 我发现 astroid 也会跟踪装饰器,所以不需要命名显式类
    • 如果您使用命令pylint -E --load-plugins pylint-decorator deco_test.py,您会看到什么。您在插件中的缩进是否与提供的代码相同?
    • 我猜,astroid.parse() 方法中的缩进错误。不再显示错误,但 pylint 似乎变得更加敏感......:D 很多评论。
    • 显式命令引发ImportError : No module named 'pylint_decorator'though。这很奇怪,因为它似乎仍然有效。
    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 2018-01-01
    • 1970-01-01
    • 2019-06-27
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多