据文件记载,
Typical implementations create a new instance of the class by invoking
the superclass’s __new__() method using super(currentclass,
cls).__new__(cls[, ...]) with appropriate arguments and then modifying
the newly-created instance as necessary before returning it.
...
If __new__ does not return an instance of cls, then the new
instance’s __init__() method will not be invoked.
号
__new__的最简单实现:
1 2 3 4
| class MyClass:
def __new__(cls):
RetVal = super(currentclass, cls).__new__(cls)
return RetVal |
super(currentclass, cls).__new__(cls[, ...])如何返回cls类型的对象?
该声明称为object.__new__(cls),其中cls是MyClass。
那么,类object如何知道如何创建类型MyClass?
- 您告诉它返回的对象应该具有什么类型。这就是cls参数的作用。
- @用户2357112我不知道你的答案。它期望的返回类型是cls。super(currentclass, cls).__new__(cls)如何返回cls?你是说它含蓄地投射了它吗?
- object.__new__看着你传递给它的cls参数,说,"哎呀,我猜阿德里安想要一个cls类型的对象。我应该做一个。"
- @用户2357112正常。那么super(class1, class2)的声明呢?它的逻辑是什么?它得到两个类共同的基类,或者什么?
- 我不是几个小时前才给你答复的吗?
- @用户2357112是否正确?"从super()开始,它本身就是super(a,b)的简写,其中a是代码发生的类,b是代码发生的函数的第一个参数;因此,在您的特定情况下,如果这是正确的,则似乎毫无意义;python不知道代码是在哪个函数中吗?
- Python怎么做有关系吗?object.__new__返回链接到类对象的新C结构。这一切都是用C语言完成的。这就是你要找的吗?
- @马蒂·皮耶特的《以东》的回答是完全有道理的,是的,这就是我要找的。我还想知道的是super后面的语法。在文件中,super(class1, class2)说issubclass(class2, class1)必须是真的。好啊.但是,super如何使用这两个类返回它返回的内容呢?
- @阿德里安:这是一个完全不同的问题,我写了几个关于super()的答案,涵盖了这个和更多的问题。
- @阿德里安:与MRO相比,函数最初定义在什么类上很重要。"魔力"__class__闭包定义了这一点。另请看一下为什么python 3.x的super()有魔力?
super(MyClass, cls).__new__(cls)首先搜索cls对象的mro(方法解析顺序)(在该序列中跳过MyClass),直到找到具有__new__属性的对象。
在您的情况下,这是object.__new__:
1 2 3 4 5 6 7 8 9
| >>> class MyClass:
... def __new__(cls):
... RetVal = super(MyClass, cls).__new__(cls)
... return RetVal
...
>>> MyClass.__mro__
(<class '__main__.MyClass'>, <class 'object'>)
>>> hasattr(MyClass.__mro__[1], '__new__')
True |
但是,如果您将MyClass子类化,并使用__new__方法将另一个类混合到MRO中,那么它可能是另一个方法。
object.__new__在c中实现,参见object_new()函数;它包含一个抽象基类挂钩,以确保您不尝试实例化一个抽象类,然后委托给tp_alloc槽,该槽通常设置为PyType_GenericAlloc,这会向堆添加一个新的PyObject结构。它是表示解释器实例的结构。
- 难道不应该用MyClass代替currentclass吗?
- @阿德里安:在你的问题上,我是以你为榜样的。是的,正确的调用将使用MyClass。
- 好啊。那么,你能指出解释super(MyClass, cls)的意思的文档吗,也就是说,super如何根据它的两个参数返回。…不管它返回什么。python.org没有说明这个信息。
- @阿德里安:那我不知道你指什么。那份文件很到位。
- 在这一环节中,我的问题的答案是:两个关于超级影响/影响返回内容的论点是怎样的?它只是说第二个参数必须是第一个参数的子类。
- @阿德里安:super(type)返回未绑定代理,super(type, object-or-type)生成绑定属性。代理使用属性访问以与getattr()相同的方式搜索mro,按该顺序跳过type。
- @阿德里安:文档假设您知道什么是MRO,什么是绑定。还要了解如何在Python中对一个参数使用super(),在这里我将深入探讨绑定的含义,以及如何在事实发生后绑定来自的一个参数。
- 在这种情况下,bound意味着什么?在我的例子中:super(myclass,cls)什么是绑定到什么,什么是"绑定"的意思?
- 好的,我会读到有关MRO和装订的资料。谢谢你抽时间
- @阿德里安:另请参阅描述符协议;绑定是在实现该协议的实例或类上查找属性时发生的事情。这就是方法如何获取self参数,以及property对象在被访问时如何最终调用函数。
很少有事情,首先您需要这样写来自object的明确继承:
您应该阅读关于python的旧类和新类(仅在python 2上,在python 3中不重要)
对于您的问题,我认为您错过了super()函数的要点或语法。同样,代码的小改动:
1
| RetVal = super(MyClass, cls).__new__(cls) |
号
通过这种方式,您可以使用super(MyClass, cls)引用父类,并从这个父类调用一个新方法(当然,您可以使用任何其他方法)。
编辑在阅读了您的评论之后,我将补充一点,super()不需要在python 3中使用任何参数,所以它对您来说可能更为琐碎。强烈建议在这里阅读更多关于super()的信息。
- 我理解预期效果。除了MyClass之外,我不知道把cls传给super还能做什么。
- 我知道issubclass(class2, class1)必须是真的,但为什么super需要cls返回它返回的内容?
- 这是关于super()的问题,而不是关于__new__()的问题。
- @Adrian我添加了链接,这样你就可以阅读更多关于它的内容,这是不同的问题,应该在不同的线程上得到答案。