避免Pylint警告E1101:'具有动态属性的类的实例...没有..成员'

fra*_*ans 50 python dynamic pylint

想象一个使用动态向对象添加属性的函数setattr.这样做的原因是我想将一些外部结构(例如给定的参数树)映射到对象:

my_object = SomeClass()
apply_structure(my_object, some_descriptor)
my_object.device1.enabled = True
Run Code Online (Sandbox Code Playgroud)

从技术上讲这是有效的,但当然Pylint正确地抱怨'device1'不是其成员SomeClass.

我可以禁用警告,但这样会很糟糕(因为我仍然希望在因错误拼写等原因而不存在该属性的情况下获得警告).

是否有一种通用且合法(Pylint-proof)的方式来动态地将成员添加到不会导致警告的对象?

或者:我可以只为一个对象而不是行/块/文件禁用Pylint 吗?

说明:

您可能想知道为什么我计划在以后以硬编码方式访问这些属性时动态地为对象配备成员属性.

原因是:我有一个动态的程序部分(装饰发生的地方)和一个专门用于特定场景的静态部分.所以我可以为这个场景创建一个静态类,但在很多情况下这样做太过分了.

以下专用代码可能允许访问可能连接到某个总线的设备的某些参数:

class MyDeviceHandler:
   on_get_some_subtree_element(self):
      return _some_internal_value
   on_set_some_subtree_element(self, value):
      _some_internal_value = value

dev = MyDeviceHandler()

decorate_object_with_device_structure(dev, 'some/attached/device')

dev.some.subtree.element = 5       <--- will call the set-callback
x = dev.some.subtree.element       <--- will call the get-callback
Run Code Online (Sandbox Code Playgroud)

所以后面的结构'some/attached/device'可能是任意的,非常复杂,我不想在类结构中重现它.

摆脱此警告的一种方法是创建/访问dict基于树的方法:

dev['some']['subtree']['element'] = 5
Run Code Online (Sandbox Code Playgroud)

但是这写起来比较难写,而且阅读起来也不好 - 我只会这样做才能让Pylint安静下来.

fra*_*ans 48

只是提供适合我的答案 - 正如编译器建议您可以为项目中的有问题的类添加规则.pylintrc:

[TYPECHECK]
ignored-classes=Fysom,MyClass
Run Code Online (Sandbox Code Playgroud)

  • 除非你添加 `str` ,否则不起作用......这似乎坏了 (2认同)

小智 17

PyLint 在两种情况下给出这种类型的错误链接

  • 当为不存在的成员访问对象(变量、函数等)时使用。

  • 误报:此消息可能会报告动态创建但在访问它们时存在的对象成员。

由于此错误被识别为 E1101 错误。您可以通过在代码中添加以下行来解决该问题。

# pylint: disable=E1101
Run Code Online (Sandbox Code Playgroud)


小智 12

该页面描述了错误,并提供了一种简单的方法直接在代码中解决该错误。tl; dr

当不存在的成员访问对象(变量,函数等)时使用。

误报:此消息可能报告动态创建的对象成员,但在访问对象成员时就存在。

评论者提到,可以使用来在文件顶部的一行中将其禁用# pylint: disable=no-member。我还发现您可以# pylint: disable=E1101基于此reddit条目使用

  • 您可以将其添加到错误所在行的末尾,以便仅禁用该行中的错误。这样您就不必在其余代码中禁用它 (10认同)
  • 简洁而全面的解决方案。这应该是公认的答案 (4认同)
  • 我认为这不是一个理想的解决方案,因为您将禁用对文件中所有代码的检查。这是一项很有价值的检查,可以发现很多实际问题。您需要对使用该类的每个文件执行此操作。理想的解决方案是 pylint 仅忽略一个类的错误。 (2认同)

Jos*_*hua 6

我能够通过将__getattr__方法添加到我的类中来避免此警告,当在对象上找不到属性时,python 会调用该方法。虽然绝对不是最干净的解决方案,但它适用于我的特定用例,因为 pylint 认为对象有效。

import warnings
class AppConfiguration(object):     
    ... 
    def __getattr__(self, name):
        ''' will only get called for undefined attributes '''
        warnings.warn('No member "%s" contained in settings config.' % name)
        return ''
Run Code Online (Sandbox Code Playgroud)

__getattr__可以在此处找到有关该方法的更多信息。


小智 5

尝试这个!我的问题解决了!

Pylint 不了解 Django 的动态文件。因此,我们需要向 Pylint 教授 Django 是什么

*适用于 Windows 10 中的 vscode *

$ pip install pylint-django
$ cd your_project_folder
$ code . // run vscode  
Run Code Online (Sandbox Code Playgroud)

在 vscode 中安装 Python、Django Snippets、Django 模板的扩展

.vscode/settings.json在vscode中打开并添加:

{
   "python.linting.pylintEnabled": true,
   "python.linting.enabled": true,
   "python.pythonPath": "venv\\Scripts\\python.exe",
   "python.linting.pylintArgs": [
       "--load-plugins",
       "pylint_django"
   ],
}
Run Code Online (Sandbox Code Playgroud)

  • 你为什么把它与 Django 联系起来? (13认同)
  • 只需添加 "python.linting.pylintArgs":[ " --load-plugins"] 对我来说就足够了。这似乎与 django 无关,因此投了反对票。 (3认同)