Python2.7下Pylint报unsupported-membership-test错误求助
Python 2.7 Pylint 报
unsupported-membership-test 错误的原因与解决方法 问题场景
我们有三个关联的Python文件:
file.py
import attr from base import BaseClass @attr.s class MyClass(BaseClass): def set_ids(self, args): if id not in self.daily.obj_dict: # do some stuff print("testing")
base.py
from abc import ABCMeta, abstractmethod from six import with_metaclass from daily import Daily class BaseClass(with_metaclass(ABCMeta, object)): @abstractmethod def set_ids(self, args): pass def process(self, vals, ids): obj_dict = { id: vals[id] for id in ids } self.daily = Daily(obj_dict)
daily.py
import attr from builtins import object @attr.s(frozen=True) class Daily(object): obj_dict = attr.ib(default=None)
在Python 2.7下执行python2.7 -m pylint file.py时,会触发以下错误:
E: 8,17: Value 'self.daily.obj_dict' doesn't support membership test (unsupported-membership-test)
而Python 3环境下执行python3 -m pylint file.py则无此错误。另外测试发现:
- 移除Daily类的
frozen=True参数后,错误消失; - 移除基类BaseClass,直接在MyClass中初始化self.daily,错误也会消失。
问题原因
- Python 2.7版Pylint对attrs frozen类的类型推导缺陷:
Python 2.7对应的旧版Pylint(如1.8及更早版本)对attrs库中frozen=True修饰的不可变类的属性类型识别能力不足,无法正确解析这类属性的实际类型。 - 继承链导致的类型追踪失效:
self.daily是在基类BaseClass中初始化的,而MyClass继承自BaseClass,Pylint在Python 2.7环境下无法跨继承层级正确追踪到self.daily.obj_dict的实际类型是dict,因此误判它不支持in成员测试。 - 非frozen类的类型识别正常:
当移除frozen=True后,attrs生成的类结构更接近普通Python类,Pylint能正常识别属性类型;直接在MyClass中初始化daily则缩短了类型追踪路径,也能让Pylint正确识别。
解决方法
1. 针对性禁用Pylint警告
如果不想修改代码结构,可以在报错行或文件级别禁用该警告:
- 单行禁用:在报错代码行上方添加注释
# pylint: disable=unsupported-membership-test if id not in self.daily.obj_dict: - 文件级禁用:在file.py的开头添加注释
# pylint: disable=unsupported-membership-test import attr from base import BaseClass
2. 添加类型注释帮助Pylint识别
在Python 2.7中可以用注释型类型提示,帮助Pylint识别属性类型:
- 在daily.py的Daily类中给obj_dict添加类型注释:
@attr.s(frozen=True) class Daily(object): obj_dict = attr.ib(default=None) # type: dict - 或者在base.py的process方法中给self.daily添加类型注释:
self.daily = Daily(obj_dict) # type: Daily
3. 移除frozen=True(业务允许的情况下)
如果你的代码不需要Daily类是不可变对象,直接去掉frozen=True参数,Pylint就能正常识别obj_dict的dict类型:
@attr.s class Daily(object): obj_dict = attr.ib(default=None)
4. 升级Python 2.7兼容的最新版Pylint
Python 2.7支持的最后一批Pylint版本(如1.9.x系列)修复了部分attrs相关的类型推导问题,可以尝试升级:
pip install --upgrade pylint==1.9.5
内容的提问来源于stack exchange,提问作者jinkins
相关产品推荐
相关产品推荐

