43

Python 2.2 的变更日志(引入了新式类)对__new__函数进行了以下说明:

__new__是静态方法,不是类方法。我最初认为它必须是一个类方法,这就是我添加classmethod原语的原因。不幸的是,对于类方法,向上调用在这种情况下无法正常工作,因此我不得不将其设为静态方法,并以显式类作为其第一个参数。

但是,我想不出为什么类方法不能用于此目的,而且它肯定会更好看。为什么最终没有__new__成为类方法?当 Guido 说“在这种情况下向上调用不起作用”时,他指的是什么?

4

1 回答 1

29

__new__当您在其中创建子类的实例时,作为静态方法允许一个用例:

return super(<currentclass>, cls).__new__(subcls, *args, **kwargs)

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

return super(<currentclass>, cls).new(*args, **kwargs)

而且没有地方放subcls

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

更常见的情况是调用 parent__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())
于 2012-02-01T08:22:27.390 回答