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

Python重写__new__限制实例数:代码疑问解析

关于Python中重写__new__方法的疑问

我在阅读一篇关于Python重写__new__方法的博客时,对下面的示例代码存在两个疑问:

class LimitedInstances(object):
    _instances = [] # Keep track of instance reference
    limit = 5
    def __new__(cls, *args, **kwargs):
        if not len(cls._instances) <= cls.limit:
            raise RuntimeError, "Count not create instance. Limit %s reached" % cls.limit
        instance = object.__new__(cls, *args, **kwargs)
        cls._instances.append(instance)
        return instance
    def __del__(self):
        # Remove instance from _instances
        self._instance.remove(self)

疑问点:

  1. 调用object.__new__(cls, *args, **kwargs)是否会导致无限递归?
  2. 已知__new__在对象创建前执行,那么cls中究竟存储的是什么?

解答

1. 为什么调用object.__new__(cls, ...)不会触发无限递归?

这是个非常关键的问题!首先得明确:只有调用当前类的__new__方法才会触发递归,而这里我们直接调用的是object类的__new__——它是所有新式类的顶级基类,不会再回调子类(也就是LimitedInstances)的__new__方法。

举个直白的例子:当你在子类里重写了某个方法,然后直接调用父类的同名方法时,只会执行父类的实现逻辑,不会绕回子类的重写方法。object.__new__的职责就是创建一个最原始的空对象实例,它内部没有任何会调用子类__new__的逻辑,所以完全不会出现无限递归的情况。

反过来,如果我们在LimitedInstances.__new__里写的是cls.__new__(cls, ...),那才会触发无限递归——因为每次调用都会回到当前方法本身,直到栈溢出报错。

2. __new__执行时,cls到底是什么?

cls其实就是当前正在被实例化的类对象本身!

你要知道,Python里的类也是一种对象:当你写完class LimitedInstances(object):这段代码时,Python就已经在内存中创建了一个名为LimitedInstances的类对象,它属于type类型(或者说,是type的实例)。

当你执行LimitedInstances()创建实例时,Python会自动调用LimitedInstances.__new__(LimitedInstances, ...)——这里的第一个参数cls,就是把LimitedInstances这个类对象直接传进来了。这时候虽然实例还没被创建,但类对象已经存在了,所以你可以正常访问cls._instances、cls.limit这些类级别的属性,就像示例代码里做的那样。

简单总结:cls是类本身的引用,让你能在__new__方法里操作类属性、控制实例的创建规则。

另外提个小细节:示例代码里的__del__方法有个笔误,应该是self._instances.remove(self)(原代码写的是self._instance.remove(self),少了一个下划线),不然运行时会抛出属性不存在的错误哦。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:20:32