为什么Python新样式类中的__new__不是类方法?

Dol*_*000 35 python language-design new-operator new-style-class

Python 2.2的Changelog(引入了新式类)说明了关于该__new__函数的以下内容:

__new__是一个静态方法,而不是类方法.我最初认为它必须是一个类方法,这就是我添加classmethod原语的原因.不幸的是,使用类方法,upcalls在这种情况下不能正常工作,因此我不得不将它作为静态方法,并将显式类作为其第一个参数.

但是,我无法想到为什么类方法不能用于此目的,它肯定会更好看.为什么最终不会__new__以类方法结束?当Guido说"在这种情况下上调不能正常工作"时,Guido会提到什么?

jfs*_*jfs 23

__new__ 当你在其中创建子类的实例时,静态方法允许用例:

return super(<currentclass>, cls).__new__(subcls, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

如果new是类方法,那么上面写的如下:

return super(<currentclass>, cls).new(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

而且没有地方可以放subcls.

不过,我真的不知道什么时候才能正确使用__new__.也许我没有看到它,但在我看来,这只是对它的完全病态使用(应该说,如果你真的想要它,那么你可以访问它object.__new__.__func__).至少,我发现很难想象它会成为Guido __new__从类方法变为静态方法的原因.

更常见的情况是在__new__不使用的情况下调用父级super().在这种情况下,您需要一个cls显式传递的位置:

class Base(object):
    @classmethod
    def new(cls):
        print("Base.new(%r)" % (cls,))
        return cls()

class UseSuper(Base):
    @classmethod
    def new(cls):
        print("UseSuper.new(%r)" % (cls,))
        return super(UseSuper, cls).new() # passes cls as the first arg

class NoSuper(Base):
    @classmethod
    def new(cls):
        print("NoSuper.new(%r)" % (cls,))
        return Base.new()  # passes Base as the first arg

class UseFunc(Base):
    @classmethod
    def new(cls):
        print("UseFunc.new(%r)" % (cls,))
        return Base.new.im_func(cls)  # or `.__func__(cls)`. # passes cls as the first arg

print(UseSuper.new())
print('-'*60)
print(NoSuper.new())
print('-'*60)
print(UseFunc.new())
Run Code Online (Sandbox Code Playgroud)

  • @Dolda2000:更常见的情况是在不使用`super()`的情况下调用父`__new__`.[在这种情况下你需要一个明确传递`cls`的地方](http://ideone.com/JdzTI). (2认同)