为什么python new样式类中的__new__不是类方法? [英] Why isn't __new__ in Python new-style classes a class method?
问题描述
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 theclassmethod
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 withobject.__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屋!