关于python源对象object的__new__(),为什么是静态方法?

class object:
    """ The most base type """
    ...

    @staticmethod # known case of __new__
    def __new__(cls, *more): # known special case of object.__new__
        """ Create and return a new object.  See help(type) for accurate signature. """
        pass
    
    ...

这里的__new__方法很奇怪,下面不是第一个参数还绑定了类(也就是源对象object自身)吗?

我的问题有几个:

  1. 为什么不是类方法?
  2. 这是个静态方法装饰器的特例吗?
  3. 除了object里面,还有别的地方这么用吗?

期待大家解答

阅读 5k
2 个回答

想通了,现列出个人的看法

作为python的源对象,object是所有类对象的祖先(base)包括另一个源对象type。其实__new__方法的第一个参数只是恰好设置成了cls,并非要绑定某个实例对象,所以可以这么回答

  1. 是静态方法,因为__new__()在这里只是一个绑定源对象object的普通方法,常规意义下__new__()的确是类方法
  2. 不是,所有的静态方法都只是绑定类对象或者实例对象的普通方法
  3. 没有,实际上是把cls这个普通的position argument和类方法当中的代表类对象的cls position argument混淆了

需要补充的是,源对象类型的实例也是类,是可以进一步实例化的,常常作为某些框架的基础数据类型描述符,可以进行强制类型检查,比如django的ORM的ModelBase,作为metaclass被所有model继承,涉及元编程的一些东西

附上官方文档的解释,以及stackoverflow一些对这个东西的讨论,很清晰,看来还是多看官方文档更有用

1.documentation

object.__new__(cls[, ...])

Called to create a new instance of class cls. __new__() is a static
method (special-cased so you need not declare it as such) that takes
the class of which an instance was requested as its first argument.
The remaining arguments are those passed to the object constructor
expression (the call to the class). The return value of __new__()
should be the new object instance (usually an instance of cls).

Typical implementations create a new instance of the class by invoking
the superclass’s __new__() method using super().__new__(cls[, ...])
with appropriate arguments and then modifying the newly-created
instance as necessary before returning it.

If __new__() returns an instance of cls, then the new instance’s
__init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as
were passed to __new__().

If __new__() does not return an instance of cls, then the new
instance’s __init__() method will not be invoked.

__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also
commonly overridden in custom metaclasses in order to customize class
creation.

2.StackOverflow的讨论

新手上路,请多包涵
A static method does not receive an implicit first argument. To declare a static method, use this idiom:
A class method receives the class as implicit first argument, just like an instance method receives the instance.
摘录于 builtins.py 模块

我觉得之所以把 __new__ 叫做 static method 是因为每次调用这个函数的时候需要 显式的 传递 cls 作为第一个参数

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题