我正在努力教授" pylint识别成员函数,我的场景可以简化为以下内容:
主要模块:a.py
from plugins import plu
class FooClass(object):
def bar(self):
self.plu.foo("asdasd")
if __name__ == '__main__':
a = FooClass()
for plugin_name, plugin in plu.plugins.items():
setattr(a, plugin_name, plugin())
a.bar()
插件文件夹文件plu.py:
plugins = {}
class Plugin(object):
def foo(self, arg):
print("bar %s" % arg)
plugins['plu'] = Plugin
插件注册自己的想法和其他一些方法"介绍"它们在FooClass
对象上。
a.py的输出是:
bar asdasd
(如预期的那样)
运行pylint -E a.py
会产生以下错误:
pylint -E a.py
************* Module a
E: 5, 8: Instance of 'FooClass' has no 'plu' member (no-member)
我曾尝试编写以下pylint-plugin:
import astroid
from astroid import nodes
def transform_test_class(mod):
if mod.name != 'a':
return
foo_cls = mod.lookup('FooClass')[1]
plugin_cls_def = astroid.MANAGER.ast_from_module_name('plugins.plu')
foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1]
def register(linter):
astroid.MANAGER.register_transform(nodes.Module, transform_test_class)
正在运行pylint --load-plugins=$(pwd)/pylint-plugin -E a.py
的输出是:
************* Module a
E: 5, 8: No value for argument 'arg' in unbound method call (no-value-for-parameter)
从错误中我怀疑我以某种方式错误地引入了属性,因为pylint认为方法foo
是无界的,但它确实是有界限的。我需要找到一种方法告诉pylint foo_cls[0].locals['plu']
实际上是类Plugin
的实例,而不是类本身。知道如何实现这一目标吗?
答案 0 :(得分:2)
将插件类添加到FooClass的本地时,需要实例化该插件类。因此,请将此行foo_cls[0].locals['plu'] = plugin_cls_def.lookup('Plugin')[1]
替换为foo_cls[0].locals['plu'] = [cls.instantiate_class() for cls in plugin_cls_def.lookup('Plugin')[1]]