Python 3.8及以下@property修饰类方法引发Logger属性错误
Python 3.8与3.9+类级@property行为差异导致的AttributeError问题
问题本质
你遇到的是Python版本对类级别属性装饰器处理逻辑的变更:
- 在Python 3.8及更早版本,
@property仅针对实例属性设计。即使你把@property用在接收cls参数的方法上,通过类名直接访问该属性时,得到的是property对象本身,不会触发getter方法的逻辑。这就是调用.info()时抛出AttributeError的原因——你在给property对象发消息,而不是实际的日志实例。 - Python 3.9开始,正式支持
@classmethod与@property的组合使用,用于定义类级别的属性。此时通过类访问该属性时,会自动调用getter方法,返回你初始化后的日志实例,因此代码能正常运行。
你的解决方案原理
移除@property装饰器后,shared_logger变成了普通的类方法,调用SingleLogger.shared_logger()会直接执行方法内的单例初始化逻辑并返回日志实例,这种写法在所有Python版本中行为一致,完全避开了版本间的属性处理差异。
兼容多版本的@property写法(可选)
如果想保留属性式访问的写法,同时兼容Python 3.8及以下版本,可以手动实现类级别的property逻辑:
import logging class SingleLogger: _instance = None @classmethod def _get_shared_logger(cls): if cls._instance is None: cls._instance = logging.getLogger("single_logger") return cls._instance # 手动绑定类级property,兼容全版本 shared_logger = property(classmethod(_get_shared_logger))
此时在所有版本中,SingleLogger.shared_logger.info("Hi")都能正常工作。
内容的提问来源于stack exchange,提问作者Jacobo
相关产品推荐
相关产品推荐

