如何在类方法中调用实例?及跨实例属性校验抛异常
问题解答
问题1:如何在类方法内部调用实例?
首先纠正你提供的Purse类代码的缩进错误(原代码中withdraw_money方法错误嵌套在__init__方法内),正确代码如下:
class Purse: def __init__( self, owner, currency="USD", ): if currency not in ("EUR", "USD"): raise ValueError self.owner = owner self.__money = 0.00 self.currency = currency def withdraw_money(self, howmany): if self.__money - howmany < 0: raise ValueError("not enough balance") self.__money = self.__money - howmany return howmany def add_money(self, howmany): self.__money += howmany return howmany
针对“类方法内部调用实例”的需求,分两种场景说明:
- 实例方法内部访问当前实例:直接用
self关键字,比如代码中的self.__money、self.currency,self就是当前实例的引用,通过它可以访问实例的属性和其他实例方法。 - 类方法内部调用实例:类方法需用
@classmethod装饰,第一个参数是cls(代表类本身),调用实例有两种方式:- 在类方法内创建新实例:
@classmethod def create_default_purse(cls, owner): new_purse = cls(owner) # 创建Purse实例 new_purse.add_money(100) # 调用实例的add_money方法 return new_purse - 接收外部传入的实例作为参数:
@classmethod def check_balance(cls, purse_instance): if not isinstance(purse_instance, cls): raise TypeError("参数必须是Purse实例") print(f"当前余额:{purse_instance._Purse__money}") # 访问私有属性(需用名称改写)
- 在类方法内创建新实例:
问题2:如何检查两个实例的属性是否不同,若不同则抛出ValueError?
针对你提到的转账场景(name1.add_money(name2.withdraw_money(value))),当两个Purse实例的currency不同时抛出ValueError,提供三种实现方式:
方式1:修改add_money方法,支持接收来源实例
调整add_money参数,允许传入转出的Purse实例,在方法内部直接检查币种:
class Purse: # 保留__init__和withdraw_money方法不变 def add_money(self, amount_or_purse, value=None): if isinstance(amount_or_purse, Purse): # 传入转出实例,执行转账逻辑 source_purse = amount_or_purse if self.currency != source_purse.currency: raise ValueError("转账双方币种不一致") withdrawn = source_purse.withdraw_money(value) self.__money += withdrawn return withdrawn else: # 普通存入金额逻辑 self.__money += amount_or_purse return amount_or_purse
调用方式改为:
name1.add_money(name2, value=50) # 直接传入转出实例和转账金额
方式2:新增专门的转账方法(更清晰)
在类中添加transfer方法,专门处理跨实例转账逻辑:
class Purse: # 保留__init__、withdraw_money、add_money方法不变 def transfer(self, target_purse, amount): if self.currency != target_purse.currency: raise ValueError("转账双方币种不一致") withdrawn = self.withdraw_money(amount) target_purse.add_money(withdrawn) return withdrawn
调用方式:
name2.transfer(name1, 50) # 从name2转50金额到name1
方式3:调用前手动检查(不修改类的情况)
如果不想修改类代码,在调用转账逻辑前先检查币种:
value = 50 if name1.currency != name2.currency: raise ValueError("币种不一致") name1.add_money(name2.withdraw_money(value))
内容的提问来源于stack exchange,提问作者Berdnikov Artemy
相关产品推荐
相关产品推荐

