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

类实例化依赖问题:Class1与Class2的实现方案哪种更优?

问题描述

我定义了Class2类,其初始化过程会创建字符串my_string以及Class1类的实例。Class1的初始化方法中调用的method需要使用my_string。我写了两种自认为最简单的实现方式,但感觉不是最优方案。请问除以下最小可行示例(MWE)外,是否存在更好的实践方案?

编辑1:
根据jonrsharpe的评论,我补充了第二个MWE。

编辑2:
以下是极简版本的类,实际代码中的类包含多个操作类内对象的方法。

MWE 1

class Class1():
    def __init__(self,object_class):
        self.method(object_class)
        
    def method(self,object_class):
        print(object_class.my_string)
        
        
class Class2():
    def __init__(self):
        self.my_string="abc"
        self.my_class=Class1(self)
        
        
test=Class2()

MWE 2

class Class1():
    def __init__(self,some_string):
        self.method(some_string)
        
    def method(self,some_string):
        print(some_string)
        
        
class Class2():
    def __init__(self):
        self.my_string="abc"
        self.my_class=Class1(self.my_string)
        
        
test=Class2()

优化方案分析

先说说你当前两种方案的问题:

  • MWE1 里Class1直接依赖整个Class2实例,耦合度太高。如果后续Class2修改了my_string的属性名,或者Class1只需要my_string但被迫持有整个Class2对象,既不灵活也容易引发不必要的依赖问题。
  • MWE2 虽然降低了耦合,但如果后续Class1需要用到Class2的其他属性或方法(比如你提到实际类有多个操作内部对象的方法),就得频繁修改Class1的初始化参数,扩展性差。

针对你的场景,推荐两种更合理的实践:

方案1:传递必要接口而非整个对象或单一值

如果Class1需要和Class2的多个属性/方法交互,但又不想耦合整个Class2,可以让Class2暴露Class1需要的必要能力,Class1只依赖这个接口:

class Class1:
    def __init__(self, string_provider):
        # 只依赖提供字符串的能力,不关心具体是哪个类
        self.string_provider = string_provider
        self.method()
        
    def method(self):
        print(self.string_provider.get_my_string())
        
class Class2:
    def __init__(self):
        self.my_string = "abc"
        self.my_class = Class1(self)
        
    def get_my_string(self):
        return self.my_string

test = Class2()

这种方式下,即使后续Class2修改了内部存储my_string的方式,只要保持get_my_string的接口不变,Class1就不需要修改,耦合度更低,扩展性更好。

方案2:按需保留弱引用,兼顾低耦合与扩展性

如果Class1大部分时候只需要my_string,但偶尔需要调用Class2的其他方法,可以在初始化时传递my_string,同时用弱引用持有Class2实例(避免循环引用导致内存泄漏):

import weakref

class Class1:
    def __init__(self, some_string, class2_instance=None):
        self.some_string = some_string
        # 弱引用避免循环引用
        self.class2_ref = weakref.ref(class2_instance) if class2_instance else None
        self.method()
        
    def method(self):
        print(self.some_string)
        
    def use_class2_other_method(self):
        # 按需获取Class2实例,处理实例已被回收的情况
        class2 = self.class2_ref()
        if class2:
            class2.other_method()

class Class2:
    def __init__(self):
        self.my_string = "abc"
        self.my_class = Class1(self.my_string, self)
        
    def other_method(self):
        print("调用Class2的其他方法")

test = Class2()
test.my_class.use_class2_other_method()

这种方式既让Class1初始化时拿到所需的my_string,又能在需要时安全调用Class2的其他能力,避免了不必要的强耦合。

总结下来,优先推荐方案1,它在低耦合和扩展性之间取得了很好的平衡,尤其适合你提到的实际类有多个内部方法的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:30:25