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

如何将新实例初始化为已有实例?Python类初始化优化问询

解决Python中__init__里直接替换self实例的问题

嘿,这个问题我太懂了!在Python的__init__里直接给self赋值根本没用——因为self只是方法的局部参数,修改它不会改变已经创建好的实例引用。不过有两个靠谱的办法能实现你想要的效果,不用手动挨个复制属性:

方法1:用__new__直接返回目标实例(推荐)

__new__才是Python类中负责创建实例的方法,__init__只是用来初始化已经创建好的实例。所以如果你的场景是要返回一个已有的实例(比如Foo(Foo(x))),直接在__new__里返回目标实例是最干净的方案。

修改你的代码如下:

from variadic_foo_operations import foo_addition, foo_multiplication

class Foo(object):
    def __new__(cls, arg=None, addends=None, factors=None):
        case_arg = arg is not None
        case_normal = case_arg and type(arg) == int
        case_trivial = case_arg and type(arg) == Foo
        case_add = addends is not None
        case_multiply = factors is not None
        case_variadic = case_add or case_multiply

        if case_trivial:
            # 直接返回传入的Foo实例,无需创建新对象
            return arg
        elif case_variadic:
            operation = foo_addition if case_add else foo_multiplication
            operands = addends if case_add else factors
            current_foo = Foo(0) if case_add else Foo(1)  # 取运算的中性元素
            for operand_foo in operands:
                current_foo = operation(current_foo, operand_foo)
            # 返回计算好的目标实例
            return current_foo
        elif case_normal:
            # 正常创建实例,交给__init__初始化
            return super().__new__(cls)
        else:
            # 处理默认情况(arg=None)
            return super().__new__(cls)
    
    def __init__(self, arg=None, addends=None, factors=None):
        # 只有正常初始化的情况才执行赋值逻辑
        case_arg = arg is not None
        case_normal = case_arg and type(arg) == int
        if case_normal:
            self.bar = arg
            self.double_bar = 2 * arg
        # trivial和variadic场景已经在__new__返回了实例,这里无需操作

这个方案的好处:

  • Foo(Foo(x))会直接返回原实例,不仅==成立,连is判断(身份相等)也成立,完全符合你的预期
  • variadic场景下直接返回计算好的实例,跳过了不必要的初始化步骤,效率更高

方法2:一行代码复制所有属性(适合不想改__new__的场景)

如果只是想在__init__里快速把目标实例的属性复制到当前self,可以用vars()方法操作实例的属性字典,一行代码搞定:

修改你__init__里的赋值部分:

if case_trivial or case_variadic:
    # 一行代码复制目标实例的所有属性到self
    vars(self).update(vars(the_foo_i_want))

解释:

  • vars(obj)会返回对象的__dict__属性(存储实例属性的字典)
  • update()方法把目标实例的所有属性键值对复制到当前self的属性字典里,省去了手动逐个赋值的麻烦

⚠️ 注意:如果你的类定义了__slots__,这个方法会失效(因为有__slots__的实例没有__dict__),但你的示例代码里没有用到__slots__,所以完全适用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 14:22:36