如何正确处理类的可变属性?保留原始PMT值的实现方案问询
如何在Borrower类中保留原始PMT值?
你的场景很常见——当类的状态(比如这里的present_value)变化后,需要保留基于初始状态计算出的结果。在Python里,有几种符合惯用风格的实现方式,我推荐下面这种封装性更好的方案:
推荐实现方案
核心思路是保存初始的本金数据,同时抽离PMT的计算逻辑,既保留原有的pmt()方法功能,又能提供获取初始PMT的途径:
import numpy as np class Borrower: def __init__(self, present_value, term, rate): self.present_value = present_value # 用下划线前缀标记内部属性,提示外部不要直接修改 self._initial_pv = present_value self.term = term self.rate = rate # 提前计算好初始PMT,避免重复计算 self._original_pmt = self._compute_pmt(self._initial_pv) def _compute_pmt(self, principal): """抽离PMT计算逻辑,方便复用和维护""" return -np.pmt(self.rate / 12, self.term, principal) def pmt(self): """返回基于当前本金的摊销值""" return self._compute_pmt(self.present_value) @property def original_pmt(self): """用property装饰器,让初始PMT像属性一样访问""" return self._original_pmt def apply_interest(self): self.present_value *= 1 + self.rate
方案优势
- 清晰的接口区分:
- 公开的
pmt()方法依旧返回基于当前状态的结果,不破坏原有逻辑; - 通过
original_pmt属性(直接访问,不用加括号)获取初始值,符合Python的属性访问习惯。
- 公开的
- 封装与复用:
- 把PMT计算逻辑抽离到
_compute_pmt私有方法中,以后如果计算规则变了,只需要修改这一个地方即可,避免重复代码。
- 把PMT计算逻辑抽离到
- 符合命名约定:
- 下划线前缀的
_initial_pv和_original_pmt明确告诉使用者,这些是类的内部属性,不要直接修改,降低误操作风险。
- 下划线前缀的
测试验证
运行下面的代码就能看到效果:
b = Borrower(1000, 12, 0.1) print(b.pmt()) # 输出 87.91... print(b.original_pmt) # 输出 87.91... b.apply_interest() print(b.pmt()) # 输出 96.70... print(b.original_pmt) # 依旧输出 87.91...,完全符合你的需求
关于你提到的初始化时保存PMT的思路
你最初想在__init__里直接保存self.init_pmt = self.pmt()的思路其实是可行的,但抽离计算逻辑的方式扩展性更好——比如如果以后你需要基于任意本金计算PMT,_compute_pmt方法可以直接复用,而不用重复写-np.pmt(...)的代码。
内容的提问来源于stack exchange,提问作者Matthew McLeod
相关产品推荐
相关产品推荐

