如何在Python类对象内部引用另一个同类型对象?(预算应用场景)
问题分析与解决方案
你当前的核心问题是缺少一个名称到对象的映射机制,无法通过类别字符串找到对应的Category实例,同时代码本身存在几个基础错误需要修正:
__init__参数命名混乱,应该传入单个类别名称而非复数形式,属性名建议用name替代categories更清晰get_balance仅累加前两项账本数据,逻辑错误,需要遍历所有账本项计算总余额transfer方法存在拼写错误(ladger→ledger),且完全没实现正确的转账逻辑:既没从当前账户扣款,也没找到目标类别对象
核心解法:类级别实例映射表
给Category类添加一个类属性,用来存储所有创建过的实例,键为类别名称,值为对应对象。这样就能直接通过字符串名称获取实例引用,完美解决你的需求。
修正后的完整代码
class Category: # 类级别的字典,统一管理所有类别实例:键=类别名称,值=Category对象 _category_registry = {} def __init__(self, category_name): self.name = category_name self.ledger = [] # 创建实例时自动注册到注册表 Category._category_registry[category_name] = self def deposit(self, amount, description=""): self.ledger.append({"amount": amount, "description": description}) def withdraw(self, amount, description=""): # 先检查余额是否足够,符合项目要求的失败返回逻辑 if self.get_balance() >= amount: self.ledger.append({"amount": -amount, "description": description}) return True return False def get_balance(self): # 遍历所有账本项,正确计算总余额 return sum(item["amount"] for item in self.ledger) def transfer(self, amount, target_category_name): # 第一步:验证目标类别是否存在 if target_category_name not in Category._category_registry: return False # 第二步:从当前账户扣款(复用withdraw方法自动记录账本) if not self.withdraw(amount, f"Transfer to {target_category_name}"): return False # 第三步:给目标账户存款 target_category = Category._category_registry[target_category_name] target_category.deposit(amount, f"Transfer from {self.name}") return True
关键逻辑说明
- 实例注册表:
_category_registry是类属性,所有Category实例共享,创建实例时自动完成注册,无需手动维护 - 转账流程:先验证目标类别存在→检查当前账户余额→扣款并记录→给目标账户存款并记录,完全符合项目对转账功能的要求
- 复用已有方法:转账时直接调用
withdraw和deposit,避免重复写账本记录逻辑,代码更简洁
补充说明
你之前考虑的全局属性思路本质和这个类属性方案一致,但类属性属于类的内部管理,更符合OOP封装原则,不需要额外的全局变量。用字符串匹配对象的核心就是维护名称-对象的映射表,这是最直接高效的解法。
内容的提问来源于stack exchange,提问作者Djery SC
相关产品推荐
相关产品推荐

