You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在类方法中调用实例?及跨实例属性校验抛异常

问题解答

问题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(代表类本身),调用实例有两种方式:
    1. 在类方法内创建新实例:
      @classmethod
      def create_default_purse(cls, owner):
          new_purse = cls(owner)  # 创建Purse实例
          new_purse.add_money(100)  # 调用实例的add_money方法
          return new_purse
      
    2. 接收外部传入的实例作为参数:
      @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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 05:06:28