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

如何实现类构造函数接收自身实例时返回原实例?

实现类似tuple的实例复用构造逻辑

这确实是个很实用的需求——让自定义类在接收自身实例作为构造参数时,直接返回原对象,完全跳过初始化流程,和tuple、frozenset这些内置类型的行为对齐。

核心解决方案就是重写__new__方法,因为它才是Python中控制实例创建的入口(__init__只是在新实例创建后做初始化)。只要在__new__中判断传入的参数是否是当前类的实例,直接返回该实例即可,这样Python会自动跳过__init__的执行,完美符合你的要求。

成熟实现代码

class MyCustomClass:
    def __new__(cls, *args, **kwargs):
        # 优先检查第一个位置参数是否为当前类的实例
        if args and isinstance(args[0], cls):
            # 返回已有实例,跳过__init__
            return args[0]
        # 正常路径:创建新实例
        return super().__new__(cls)
    
    def __init__(self, value):
        print("执行__init__初始化")
        self.value = value

测试验证

# 创建新实例,会触发__init__
obj1 = MyCustomClass(42)
# 传入已有实例,直接返回原对象,__init__不会执行
obj2 = MyCustomClass(obj1)

print(obj1 is obj2)  # 输出: True,证明是同一个对象
print(obj2.value)    # 输出: 42,直接复用原实例的属性

关键细节说明

  • __new__是类的特殊静态方法,它的返回值决定了后续是否执行__init__:如果返回的是当前类的新实例,Python会自动调用__init__;如果返回的是已存在的实例,__init__会被直接跳过,这正是我们需要的。
  • 上面的代码只检查了第一个位置参数,你可以根据业务需求调整判断逻辑——比如支持通过关键字参数传入实例,或者同时检查多个参数。
  • 对于子类继承场景,isinstance(args[0], cls)依然有效,因为它会识别子类实例(如果需要严格匹配当前类,可以用type(args[0]) is cls)。

扩展场景示例

如果需要支持通过关键字参数传入实例,比如MyCustomClass(instance=obj1),可以修改__new__如下:

def __new__(cls, *args, **kwargs):
    # 检查位置参数
    if args and isinstance(args[0], cls):
        return args[0]
    # 检查关键字参数
    if 'instance' in kwargs and isinstance(kwargs['instance'], cls):
        return kwargs['instance']
    # 正常创建实例
    return super().__new__(cls)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:44:48