分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击人工智能教程​​​​https://www.captainai.net/troubleshooter

这两个方法是 Python 类中的特殊方法,用于控制对象的创建和初始化,但它们的作用和执行时机完全不同。

一、核心区别

特性__new____init__
作用创建实例对象初始化实例对象
调用时机在 __init__ 之前在 __new__ 之后
第一个参数cls(类本身)self(实例对象)
返回值必须返回实例对象不返回(返回 None)
是否必须可选,一般不需要重写可选,常用
使用场景控制实例创建过程设置实例属性

二、执行顺序

class MyClass:
    def __new__(cls, *args, **kwargs):
        print("1. __new__ 被调用")
        instance = super().__new__(cls)
        print(f"   创建实例: {instance}")
        return instance
    
    def __init__(self, value):
        print("2. __init__ 被调用")
        self.value = value
        print(f"   初始化实例: {self}")

obj = MyClass(10)
print(f"最终对象: {obj}")

输出:

1. __new__ 被调用
   创建实例: <__main__.MyClass object at 0x...>
2. __init__ 被调用
   初始化实例: <__main__.MyClass object at 0x...>
最终对象: <__main__.MyClass object at 0x...>

三、详细说明

__new__ 方法

  • 类方法(虽然不用 @classmethod 装饰)

  • 负责分配内存,创建实例对象

  • 必须返回一个实例对象(通常是 cls 的实例)

  • 如果 __new__ 返回的不是当前类的实例,__init__ 不会被调用

__init__ 方法

  • 实例方法

  • 负责初始化已创建的实例

  • 设置实例属性

  • 不应该返回任何值(返回 None)

四、典型使用场景

1. 单例模式

class Singleton:
    _instance = None
    
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            print("创建单例实例")
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def __init__(self, value):
        print("初始化单例")
        self.value = value

# 测试
s1 = Singleton(10)
s2 = Singleton(20)
print(s1 is s2)  # True(同一个对象)
print(s1.value)  # 20(最后初始化的值)

输出:

创建单例实例
初始化单例
初始化单例
True
20

2. 不可变类(如继承 int、str)

class PositiveInteger(int):
    def __new__(cls, value):
        # 在创建之前进行验证
        if value <= 0:
            raise ValueError("必须是正整数")
        # 创建整数对象
        return super().__new__(cls, value)
    
    def __init__(self, value):
        # int 是不可变类型,__init__ 中无法修改值
        print(f"创建正整数: {value}")

try:
    n1 = PositiveInteger(5)   # 正常
    n2 = PositiveInteger(-3)  # 抛出异常
except ValueError as e:
    print(e)  # 必须是正整数

3. 缓存对象

class CachedObject:
    _cache = {}
    
    def __new__(cls, key, value):
        # 如果对象已存在,直接返回缓存的对象
        if key in cls._cache:
            print(f"从缓存返回对象: {key}")
            return cls._cache[key]
        
        # 创建新对象
        print(f"创建新对象: {key}")
        instance = super().__new__(cls)
        cls._cache[key] = instance
        return instance
    
    def __init__(self, key, value):
        # 避免重复初始化
        if hasattr(self, '_initialized'):
            return
        print(f"初始化对象: {key}")
        self.key = key
        self.value = value
        self._initialized = True

# 测试
obj1 = CachedObject("a", 1)
obj2 = CachedObject("a", 2)  # 从缓存返回,不会重新初始化
print(obj1 is obj2)  # True
print(obj2.value)    # 1(保留第一次初始化的值)

输出:

创建新对象: a
初始化对象: a
从缓存返回对象: a
True
1

4. 子类化不可变类型

class SliceRange(tuple):
    """自定义范围类,基于 tuple"""
    def __new__(cls, start, end, step=1):
        # 创建元组
        if step > 0:
            values = range(start, end, step)
        else:
            values = range(start, end, step)
        return super().__new__(cls, values)
    
    def __init__(self, start, end, step=1):
        # 存储参数供方法使用
        self.start = start
        self.end = end
        self.step = step

sr = SliceRange(1, 10, 2)
print(sr)           # (1, 3, 5, 7, 9)
print(sr.start)     # 1
print(len(sr))      # 5

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐