避免 Pylint 警告 E1101: 对于具有动态属性的类,“实例的. . has no. . member”

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

my_object = SomeClass()
apply_structure(my_object, some_descriptor)
my_object.device1.enabled = True

从技术上讲,这是可行的,但是当然 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

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

消除这种警告的一种方法是创建/访问一个基于 dict的树:

dev['some']['subtree']['element'] = 5

但是这个更难写,也不好读——我这样做只是为了让 Pylint 安静下来。

111153 次浏览

Just to provide the answer that works for me now - as The Compiler suggested you can add a rule for the problematic class in your projects .pylintrc:

[TYPECHECK]
ignored-classes=Fysom,MyClass

This page describes the error and gives an easy way to address it directly in the code. tl;dr

Used when an object (variable, function, …) is accessed for a non-existent member.

False positives: This message may report object members that are created dynamically, but exist at the time they are accessed.

A commentor mentions that it can be disabled on a single line at the top of the file with # pylint: disable=no-member. I also found that you can use # pylint: disable=E1101 based on this reddit entry.

Try this! My problem solved!

Pylint doesn't understand the Django's dynamic filed. Thus, we need to teach what the Django is to Pylint

*for vscode in Windows 10 *

$ pip install pylint-django
$ cd your_project_folder
$ code . // run vscode

Install extension for Python, Django Snippets, Django Template in vscode

Open .vscode/settings.json in vscode and add:

{
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"python.pythonPath": "venv\\Scripts\\python.exe",
"python.linting.pylintArgs": [
"--load-plugins",
"pylint_django"
],
}

PyLint gives this type of errors on two cases Link:

  • Used when an object (variable, function, …) is accessed for a non-existent member.

  • False positives: This message may report object members that are created dynamically, but exist at the time they are accessed.

As this error is identified as E1101 error. You can solve the issue by adding the following line in your code.

# pylint: disable=E1101

For me just installing pylint-django solved the issue:

pip install pylint-django

I was able to avoid this warning by adding the __getattr__ method to my class, which python calls when an attribute is not found on an object. Although definitely not the cleanest solution, it worked for my particular use-case as pylint considers the object valid.

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 ''

More information about the __getattr__ method can be found here.

Hesitate to add to this answer, since I'd prefer if there was an explicit way to do this with pylint. But there is a hack around solution that is working (at least as of pylint 2.7.4). In this example code I use a "getattr" null-op to prevent pylint from thinking it knows anything about the object. Obviously something this simple might not continue working going forward, but I like the fact that you can control which exact things you want pylint to ignore without having to touch anything other than source file, and without having to disable the check globally throughout the source file.

class MyClass():
"""an empty class"""


myc = MyClass()
print(myc.hello_world)  # pylint no-member
myc = globals()['myc']
print(myc.hello_world)  # no error flagged


class MyDeviceHolder1():
"""a device holder class"""
def __init__(self):
self.devices = MyClass()


mdh1 = MyDeviceHolder1()
print(mdh1.devices.hello_world)  # pylint no-member


class MyDeviceHolder2():
"""a device holder class"""
def __init__(self):
self.devices = MyClass()
self.devices = getattr(self, 'devices')


mdh2 = MyDeviceHolder2()
print(mdh2.devices.hello_world)  # no error flagged
print(mdh2.devixes.hello_world)  # pylint no-member

Another possible reason for getting the no-member is, that the self argument of the __init_() method of this class is missing:

Wrong:

class foo:
def __init__(bar):
self.bar = bar

Right:

class foo:
def __init__(self, bar):
self.bar = bar

Application code to get the no-member warning:

x = foo('bar')
print(x.bar) # <-- this line will be the reported error line