优先使用 hasattr() 和 getattr() 进行属性存在性判断与默认值获取,避免 try-except 异常流控;对字典式对象优先用 .get();仅在触发副作用或复杂逻辑时才用明确类型的 try-except。

直接用 hasattr() 或 getattr() 配合默认值,比反复 try-except 更轻量、更直观,尤其适合属性存在性判断这类高频操作。
优先用 hasattr() 和 getattr() 做“试探性访问”
当目标是确认某个对象是否有某属性(而非执行可能出错的操作),hasattr(obj, 'attr') 是最自然的选择。它内部调用 getattr(obj, 'attr', <span style="color:#0000FF">sentinel</span>) 并检查是否返回哨兵值,安全且语义清晰。
若需取值并提供兜底,直接用 getattr(obj, 'attr', 'default')。它不抛异常,也不触发属性访问的副作用(比如 property 的 getter),适合配置读取、字段 fallback 等场景。
- 避免为单纯判断属性是否存在而写
try: obj.attr ... except AttributeError: ...—— 这属于“用异常流控”,开销大、可读性弱 -
hasattr和getattr对大多数内置类型和常规类都可靠;仅对重载了__getattr__且行为异常的对象需额外留意
对动态或不确定结构的对象,用字典式访问更稳妥
如果对象本质是类似字典的结构(如 types.SimpleNamespace、dataclass 实例、或自定义支持 __getitem__ 的类),优先走 .get() 接口:
-
obj.__dict__.get('attr')直接查实例字典,快且无副作用 - 若对象实现了
__getitem__,用obj.get('attr', default)(前提是它暴露该方法) - 对 JSON-like 数据(如
dict或AttrDict),统一用.get()风格,逻辑一致、不易出错
真正需要 try-except 的场景:触发副作用或复杂逻辑时
当访问属性会执行实际操作(如 lazy-load、远程调用、计算属性),且该操作本身可能失败,才应捕获 AttributeError 或更具体的异常:
- 例如:
user.profile.bio触发数据库查询,可能抛DatabaseError,这时hasattr无意义,必须try-except - 捕获时明确异常类型:
except AttributeError处理属性不存在,except ValueError处理值解析失败,不写裸except: - 可在
except中记录日志或降级处理,但不要掩盖原始错误堆栈,必要时用raise ... from e保留上下文
自定义类中主动控制属性行为
在你定义的类里,可通过 __getattr__ 统一处理缺失属性,避免上层频繁判空:
- 返回默认值、抛业务异常(如
MissingConfigError),或触发 fallback 逻辑 - 配合
__slots__提前约束属性集,让AttributeError更早暴露问题,而不是运行时才发现 - 对关键属性,用 property + 显式校验,在设置阶段拦截非法状态,比在访问时补救更高效

















