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

在类中创建其他类实例时,是否应传递自身(self)?

嘿,这个问题我碰到过好多次了,先给你拍板:直接传递self的方式确实能跑起来,但真算不上什么好做法。咱们来掰扯清楚为啥,还有哪些更靠谱的方案~

先说说传self的问题

首先得承认,它确实能实现需求——毕竟self带着调用类A的所有属性,被调用类B拿到后就能直接用x、y这些值。但它的问题也很突出:

  • 耦合度拉满:类B直接绑定了A的内部结构,如果哪天你把A里的self.x改成self.x_value,B里所有用到x的地方都得跟着改,维护起来特别闹心。
  • 违反单一职责:类B本来该专注于自己的业务逻辑,结果现在还得摸清A的内部细节,完全不符合面向对象的设计思路。
  • 复用性为零:以后想在别的类里用B?那得保证那个类也有x、y这些属性,不然B直接罢工。
更优的几种替代方案

1. 只传需要的具体参数(最推荐!)

既然B只需要x和y,那就别把整个self塞给它,只传这两个具体的值就行。这样一来,A和B彻底解绑,B的依赖一目了然,复用性也直接拉满。
示例代码:

class A:
    def __init__(self):
        self.x = 1
        self.y = 10
        # 只传递B真正需要的参数
        self.my_obj = B(self.x, self.y)

class B:
    def __init__(self, x, y):
        self.x = x
        self.y = y

这种方式的好处:

  • 看B的__init__就知道它需要啥,一目了然
  • A和B的耦合降到最低,改A的属性名只需要在传参时对应调整,完全不用碰B的代码
  • B可以被任何有x、y值的类调用,通用性极强

2. 用数据类封装参数(参数超多时用)

要是需要传递的参数特别多(比如七八个甚至十几个),一个个传太啰嗦,这时候可以把这些参数封装成一个数据类(Python自带的dataclasses就很方便),然后传递这个数据对象。
示例代码:

from dataclasses import dataclass

@dataclass
class BConfig:
    x: int
    y: int
    # 其他需要的参数都放这儿...

class A:
    def __init__(self):
        self.config = BConfig(x=1, y=10)
        self.my_obj = B(self.config)

class B:
    def __init__(self, config: BConfig):
        self.x = config.x
        self.y = config.y

这种方式既避免了参数列表过长,又保持了低耦合,而且数据类自带比较、打印等便捷功能,维护起来省心不少。

3. 依赖注入(复杂项目首选)

如果你的项目规模比较大,类之间的依赖关系错综复杂,可以试试依赖注入:把B的实例创建逻辑从A里抽出来,交给外部负责创建后再注入到A中。
示例代码:

class A:
    def __init__(self, my_obj):
        self.x = 1
        self.y = 10
        self.my_obj = my_obj

class B:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 外部统一管理实例创建和注入
b_instance = B(x=1, y=10)
a_instance = A(my_obj=b_instance)

这种方式下,A完全不需要知道B的创建细节,甚至可以轻松替换成B的子类,灵活性拉满,特别适合大型项目的模块化开发。

最后总结下
  • 传self能工作,但强烈不推荐,耦合太高坑自己
  • 优先选传递具体参数,简单直接,解耦效果最好
  • 参数多就用数据类封装
  • 复杂场景果断上依赖注入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:11:27