Pylint无法识别@cached_property可迭代性,误报E1133(not-an-iterable)错误
解决pylint对@cached_property装饰的可迭代属性报E1133(not-an-iterable)的问题
问题现象
- 用第三方
cached_property装饰器标记的类属性,明明返回可迭代类型(比如List[str]),pylint却抛出E1133: Non-iterable value Bike().tires is used in an iterating context (not-an-iterable)错误 - 换成标准库的
@property装饰同名属性时,pylint完全不会报错,且两种写法的代码实际运行都正常,能正常迭代属性值
有问题的代码示例(@cached_property版本)
# doodle.py from typing import List from cached_property import cached_property class Bike: @cached_property def tires(self) -> List[str]: return ["front", "back"] front_tire = [tire for tire in Bike().tires if tire == "front"]
正常的代码示例(@property版本)
class Bike: @property def tires(self): return ["front", "back"] front_tire = [tire for tire in Bike().tires if tire == "front"]
原因分析
这不是代码功能bug,而是pylint的类型推断局限导致的:第三方cached_property装饰器的类型定义没有被pylint正确识别,它无法推断出装饰后的属性仍然保留了原方法的返回类型(可迭代的列表)。而标准库的@property是pylint内置支持的装饰器,能正确解析其类型信息,所以不会误报。
解决方法
1. 改用标准库的functools.cached_property(推荐)
Python 3.8及以上版本的标准库functools自带了cached_property装饰器,pylint对标准库的支持更完善,完全不会出现这个误报:
from typing import List from functools import cached_property class Bike: @cached_property def tires(self) -> List[str]: return ["front", "back"] front_tire = [tire for tire in Bike().tires if tire == "front"]
2. 给属性显式添加类型注解
如果必须使用第三方cached_property包,可以在类中给属性显式声明类型,辅助pylint识别:
from typing import List from cached_property import cached_property class Bike: @cached_property def tires(self) -> List[str]: return ["front", "back"] # 显式声明属性类型,让pylint正确识别 tires: List[str]
3. 配置pylint信任cached_property装饰器
在pylint的配置文件(如.pylintrc)中,将cached_property加入信任装饰器列表,让pylint把它视为和@property类似的装饰器处理:
在配置文件的[TYPECHECK]部分添加:
trusted-decorators=cached_property
内容的提问来源于stack exchange,提问作者Hommes
相关产品推荐
相关产品推荐

