本文介绍如何在python类中正确设计__str__方法,并结合@property装饰器安全、清晰地暴露实例属性,避免命名冲突与逻辑错误,从而实现灵活且可读性强的字符串格式化输出。
本文介绍如何在python类中正确设计__str__方法,并结合@property装饰器安全、清晰地暴露实例属性,避免命名冲突与逻辑错误,从而实现灵活且可读性强的字符串格式化输出。
在Python面向对象编程中,__str__方法用于定义对象被print()或str()调用时返回的人类可读字符串表示。但要让该方法准确反映对象状态,关键在于:
- 确保所访问的属性真实存在且命名无误;
- 避免方法名与属性名冲突(如原代码中balance()方法与self.balance属性同名,导致无限递归);
- 提升接口清晰度——使用@property将计算逻辑或简单封装包装为“属性式访问”,语义更自然。
以下是一个规范、健壮的实现示例:
class Account:
def __init__(self, name: str, value: float):
self.name = name
self.value = value
@property
def Owner(self) -> str:
"""只读属性:账户所有者姓名"""
return self.name
@property
def Balance(self) -> float:
"""只读属性:账户余额(单位:美元)"""
return self.value
def __str__(self) -> str:
return f'Account owner: {self.Owner}\nAccount balance: ${self.Balance:.2f}'
✅ 关键改进说明:
- 使用@property将Owner和Balance声明为只读属性,外部可直接以acct.Owner方式访问,无需括号调用,语义更贴近“数据字段”;
- __str__内部调用self.Owner和self.Balance,而非直接访问self.name/self.value,既保持封装性,又便于未来扩展(例如添加格式化、权限校验等逻辑);
- f-string中使用:.2f确保余额始终保留两位小数,提升输出一致性;
- 移除了原代码中危险的def balance(self): return self.balance——该写法会触发无限递归(方法名与属性名冲突),Python解释器将报RecursionError。
? 使用示例:
if __name__ == '__main__':
acct = Account("TomServo", 100.4)
print(acct)
输出:
Account owner: TomServo Account balance: $100.40
⚠️ 注意事项:
- 若需支持修改(如存取款),应配套提供@Balance.setter;当前示例为只读设计,符合金融类数据的安全惯例;
- 属性名建议采用PascalCase(如Owner/Balance)以区别于普通字段(name/value),增强可读性与IDE提示准确性;
- __str__应始终返回str类型,不可返回None或其它类型,否则会引发TypeError。
掌握这一模式,你不仅能精准控制对象打印行为,还能构建出结构清晰、易于维护且符合Python惯用法的类接口。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











