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

如何创建类构造函数:输入为该类实例时不执行任何操作?

实现传入实例时直接返回的类构造函数

问题分析

你需要让类的构造函数支持两种输入:如果输入是该类的实例,直接返回该实例;如果是原始数据,则正常创建并初始化实例。原代码用__init__无法实现,因为__init__是初始化已创建的实例,且返回值会被忽略,必须通过重写__new__方法来实现。

解决方案:重写__new__方法

__new__是Python类的构造方法,负责创建实例,它可以直接返回已有的实例。结合__init__的判断逻辑,就能实现需求:

示例1:Apple类的实现

class Apple:
    def __new__(cls, *args, **kwargs):
        # 检查是否传入单个参数且为当前类的实例,无额外关键字参数
        if len(args) == 1 and len(kwargs) == 0 and isinstance(args[0], cls):
            return args[0]
        # 否则创建新实例
        return super().__new__(cls)
    
    def __init__(self, *args):
        # 仅当实例未初始化时执行解析逻辑
        if not hasattr(self, '_seeds'):
            self._seeds = "".join(str(arg) for arg in args)

测试验证:

a1 = Apple(1, 2, 3)
a2 = Apple(a1)
print(a1 is a2)  # 输出: True(同一实例)
print(a2._seeds) # 输出: "123"

示例2:通用ParsedData类

针对你的通用需求(接受已解析实例或原始数据),可以这样实现:

class ParsedData:
    def __new__(cls, data):
        # 直接判断输入是否为当前类实例
        if isinstance(data, cls):
            return data
        # 创建新实例
        return super().__new__(cls)
    
    def __init__(self, data):
        # 仅初始化未处理过的实例
        if not hasattr(self, '_parsed'):
            # 模拟数据解析过程
            self._parsed = data.upper() if isinstance(data, str) else str(data)

测试验证:

raw_data = "hello world"
parsed1 = ParsedData(raw_data)
parsed2 = ParsedData(parsed1)
print(parsed1 is parsed2)  # 输出: True
print(parsed2._parsed)     # 输出: "HELLO WORLD"

关键说明

  1. __new__的作用:作为类的构造方法,它的第一个参数是类本身(cls),可以返回任意实例(包括已有实例),这是实现需求的核心。
  2. __init__的判断:当__new__返回已有实例时,Python仍会调用__init__,所以需要在__init__中通过属性检查(如hasattr)跳过重复初始化逻辑。
  3. 原代码的问题:原代码使用__init__无法实现,因为__init__的返回值会被忽略,且无法阻止新实例的创建;同时代码中other变量未定义,应为args[0]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:10:18