全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 10 分钟 ✍️ juanwangdev

Python __new__方法

__new__是对象创建的第一步,负责分配内存并返回实例,__init__随后初始化实例。

newinit 区别

Python
class Demo:
    def __new__(cls, *args, **kwargs):
        print("1. __new__: 创建对象")
        instance = super().__new__(cls)
        return instance

    def __init__(self, *args, **kwargs):
        print("2. __init__: 初始化对象")
        self.value = args[0] if args else None

obj = Demo("test")
# 输出顺序:
# 1. __new__: 创建对象
# 2. __init__: 初始化对象
方法职责参数返回值
__new__创建对象cls + 参数实例对象
__init__初始化对象self + 参数None
Python
# __new__ 可以决定是否调用 __init__
class SkipInit:
    def __new__(cls, *args, **kwargs):
        print("__new__ called")
        # 返回其他类或 None 会跳过 __init__
        return None

    def __init__(self):
        print("__init__ called")  # 不会执行

obj = SkipInit()
print(obj)  # None

单例模式实现

Python
class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, value):
        # 注意:每次调用都会执行 __init__
        self.value = value

s1 = Singleton(1)
s2 = Singleton(2)

print(s1 is s2)       # True(同一实例)
print(s1.value)       # 2(被第二次 __init__ 覆盖)
Python
# 完善的单例:避免重复 __init__
class ProperSingleton:
    _instance = None
    _initialized = False

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self, value):
        if not self._initialized:
            self.value = value
            self._initialized = True

s1 = ProperSingleton(1)
s2 = ProperSingleton(2)

print(s1.value)       # 1(未被覆盖)
print(s1 is s2)       # True
Python
# 多例模式(有限实例)
class Multiton:
    _instances = {}

    def __new__(cls, key):
        if key not in cls._instances:
            cls._instances[key] = super().__new__(cls)
        return cls._instances[key]

a1 = Multiton('A')
a2 = Multiton('A')
b1 = Multiton('B')

print(a1 is a2)       # True
print(a1 is b1)       # False

控制实例类型

Python
# 根据参数返回不同子类
class Shape:
    def __new__(cls, sides, **kwargs):
        if sides == 3:
            return Triangle(**kwargs)
        elif sides == 4:
            return Rectangle(**kwargs)
        elif sides == 5:
            return Pentagon(**kwargs)
        else:
            return super().__new__(cls)

class Triangle(Shape):
    def __init__(self, **kwargs):
        self.sides = 3
        self.name = "triangle"

class Rectangle(Shape):
    def __init__(self, **kwargs):
        self.sides = 4
        self.name = "rectangle"

class Pentagon(Shape):
    def __init__(self, **kwargs):
        self.sides = 5
        self.name = "pentagon"

tri = Shape(3)
rect = Shape(4)
print(type(tri).__name__)    # Triangle
print(type(rect).__name__)   # Rectangle

不可变对象实现

Python
# 模拟 tuple 的不可变性
class ImmutablePoint:
    __slots__ = ('_x', '_y')

    def __new__(cls, x, y):
        instance = super().__new__(cls)
        instance._x = x
        instance._y = y
        return instance

    def __init__(self, x, y):
        # __init__ 不设置值,避免重复初始化问题
        pass

    @property
    def x(self):
        return self._x

    @property
    def y(self):
        return self._y

    def __setattr__(self, name, value):
        raise AttributeError("不可变对象")

p = ImmutablePoint(1, 2)
print(p.x, p.y)       # 1 2
# p.x = 10            # AttributeError

继承不可变类型

Python
# 继承 tuple
class NamedTuple(tuple):
    "带名称的元组"

    __slots__ = ()  # 避免创建 __dict__

    def __new__(cls, name, values):
        # tuple.__new__ 接受可迭代对象
        instance = super().__new__(cls, values)
        instance._name = name  # 通过 __new__ 添加属性
        return instance

    @property
    def name(self):
        return self._name

nt = NamedTuple("coordinates", (1, 2, 3))
print(nt.name)        # coordinates
print(nt[0])          # 1
Python
# 继承 int
class PositiveInt(int):
    "正整数类型"

    def __new__(cls, value):
        if value < 0:
            raise ValueError("必须是正整数")
        return super().__new__(cls, value)

    def __repr__(self):
        return f"PositiveInt({self})"

n = PositiveInt(10)
print(n + 5)          # 15(继承 int 的运算)
print(type(n))        # PositiveInt

# PositiveInt(-1)     # ValueError

缓存实例

Python
class CachedInstance:
    "缓存已创建的实例"

    _cache = {}
    _cache_limit = 100

    def __new__(cls, key):
        # 检查缓存
        if key in cls._cache:
            return cls._cache[key]

        # 创建新实例
        instance = super().__new__(cls)

        # 缓存管理
        if len(cls._cache) >= cls._cache_limit:
            cls._cache.clear()

        cls._cache[key] = instance
        return instance

    def __init__(self, key):
        self.key = key

a1 = CachedInstance('a')
a2 = CachedInstance('a')
b = CachedInstance('b')

print(a1 is a2)       # True(缓存命中)
print(a1 is b)        # False

new 与描述符

Python
class Descriptor:
    def __set_name__(self, owner, name):
        self.name = name

    def __get__(self, obj, owner):
        if obj is None:
            return self
        return getattr(obj, f'_internal_{self.name}', None)

    def __set__(self, obj, value):
        setattr(obj, f'_internal_{self.name}', value)

class Controlled:
    attr = Descriptor()

    def __new__(cls, *args, **kwargs):
        instance = super().__new__(cls)
        # __new__ 中可以设置描述符控制的属性
        setattr(instance, '_internal_attr', kwargs.get('attr', 0))
        return instance

    def __init__(self, **kwargs):
        # __init__ 中通过描述符设置
        if 'attr' in kwargs:
            self.attr = kwargs['attr']

obj = Controlled(attr=10)
print(obj.attr)       # 10

跳过 init 的场景

Python
class DatabaseConnection:
    "数据库连接:__new__ 完成核心初始化"

    def __new__(cls, url):
        instance = super().__new__(cls)
        # 连接数据库
        instance._url = url
        instance._connected = True
        return instance

    def __init__(self, url):
        # __init__ 可能被多次调用,避免重复初始化
        if not hasattr(self, '_setup_done'):
            self._setup_done = True
            # 其他配置

conn = DatabaseConnection("postgres://...")
# __new__ 已完成连接,__init__ 仅做额外配置

要点总结

  1. **__new__创建对象,__init__**初始化对象
  2. __new__返回其他对象或None会跳过__init__
  3. 单例模式通过__new__控制实例数量
  4. 继承不可变类型(tuple、int)必须用__new__设置值
  5. __new__可实现实例缓存、类型选择等高级控制

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python __init_subclass__
下一篇 → Python eval与exec安全使用
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库