为什么python new样式类中的__new__不是类方法? [英] Why isn't __new__ in Python new-style classes a class method?

查看:366
本文介绍了为什么python new样式类中的__new__不是类方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The Changelog for Python 2.2 (where new-style classes were introduced) says the following about the __new__ function:

__new__是静态方法,不是类方法.我最初以为它必须是一个类方法,这就是为什么我添加了classmethod原语的原因.不幸的是,在使用类方法的情况下,向上调用在这种情况下无法正常工作,因此我必须使其成为一个以显式类作为第一个参数的静态方法.

__new__ is a static method, not a class method. I initially thought it would have to be a class method, and that's why I added the classmethod primitive. Unfortunately, with class methods, upcalls don't work right in this case, so I had to make it a static method with an explicit class as its first argument.

但是,我无法想到为什么类方法不能用于此目的,并且看起来肯定更好.为什么__new__最终没有成为类方法? Guido说在这种情况下无法正常使用通话"时指的是什么?

However, I cannot think of why class methods wouldn't work for this purpose, and it would certainly look better. Why didn't __new__ end up as a class method in the end? What does Guido refer to when he says that "upcalls don't work right in this case"?

推荐答案

__new__作为静态方法,当您在其中创建子类的实例时,便可以使用:

__new__ being static method allows a use-case when you create an instance of a subclass in it:

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

如果new是类方法,则以上内容将写为:

If new is a class method then the above is written as:

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

,没有放置subcls的地方.

不过,我真的不知道何时适当使用__new__.也许我没有看到它,但是在我看来,它完全是病理上的使用(应该说,如果您仍然真正想要它,则可以使用object.__new__.__func__访问它).至少,我很难想象这是Guido将__new__从类方法更改为静态方法的原因.

I don't really see when that would be a proper use of __new__, though. Maybe I'm not seeing it, but that just seems to me to be a completely pathological use of it (and it should be said, that if you still really want it, then you could access it with object.__new__.__func__). At the very least, I find it very hard to imagine that it would have been the reason for Guido to change __new__ from being a class method to a static method.

更常见的情况是不使用super()来调用父级__new__. 在这种情况下,您需要一个地方明确地通过cls :

A more common case would be to call parent __new__ without using super(). You need a place to pass cls explicitly in this case:

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())

这篇关于为什么python new样式类中的__new__不是类方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆