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

Python如何跨类调用其他类方法避免AttributeError

问题原因

报错本质是设计缺陷导致的:

  • B类与C类无继承关系,B实例自身不存在_request属性,直接调用self._request必然找不到对应方法
  • C类的_request方法强依赖调用实例持有token属性,就算强行给B实例绑定_request方法,B实例没有token属性依然会触发属性错误
  • A类的get_b_obj方法生成B实例时,没有将自身持有的请求能力、token上下文传递给B对象,导致B完全缺失发起请求的必要依赖
  • 原FILE_3.py中from FILE_2 import _C属于错误导包,FILE_2中不存在名为_C的对象
正确修复方式

通过依赖注入的方式,在创建B实例时将当前持有token、具备_request调用能力的A实例传入B,B调用请求方法时直接使用传入的A实例上下文即可,不需要修改C类的请求逻辑,也不需要给B加多余的继承关系。

各文件修改后代码如下:

FILE_1.py

from FILE_2 import C
from FILE_3 import B

class A(C):
    def __init__(self, token):
        self.token = token

    def update_something(self):
        self._request(body={'to_update': 'something'})

    def get_b_obj(self, name):
        # 生成B实例时,将当前A实例自身作为参数传入
        return B(name, self)

FILE_2.py

无需修改,保持原有请求封装逻辑即可:

import requests

class C:
    def _request(self, body=None):
        headers = {'token': self.token}
        requests.get('https://example.com', headers=headers, json=body)

FILE_3.py

移除错误导包,构造方法增加A实例参数,调用请求时走传入的A实例方法:

class B:
    def __init__(self, name, a_client):
        self.name = name
        # 持有带token、具备请求能力的A实例引用
        self.a_client = a_client

    def change_name(self, new_name):
        # 调用A实例继承自C的_request方法,方法执行时的self指向持有token的A实例,无属性错误
        self.a_client._request(body={'new_name': new_name})

执行验证

原有执行逻辑无需改动,运行后可正常发起请求:

main_obj = A(token="ABC123")
new_b = main_obj.get_b_obj("name")
new_b.change_name("new_name")
不推荐的错误写法
  • 让B类继承C类:B实例自身不持有token,继承_request后调用时依然会因为找不到self.token报错
  • 动态给B实例绑定A的_request方法:属于隐式依赖,代码可维护性极差,后续排查问题时无法快速定位B实例的请求方法来源
  • 在B实例中重新初始化一个A对象:会导致token需要重复传入,破坏原有A实例的上下文一致性,容易出现多实例token不同步的问题

内容的提问来源于stack exchange,提问作者David Lev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:45:40