从坚果壳中的Python
super(cls,obj)
返回super
- 对象obj
的对象(必须是类cls
或cls
的任何子类的实例),适合用于调用超类方法。
来自https://docs.python.org/3.6/library/functions.html#super
super([type[, object-or-type]])
返回代理对象,将方法调用委托给type
的父级或同级类。
A comment by Martijn Pieters表示super(cls,obj)
的返回对象是代理设计模式的一个示例。
Gamma等人在设计模式中the proxy design pattern is implemented by inheriting the class of the subject of proxy。
但是我发现super
类仅从object
继承,而不是从代理主题继承而来,这是#34; type
&#的父类或兄弟类34 ;.
所以我想知道super
类如何实现代理设计模式?通过鸭子打字?
感谢。
答案 0 :(得分:1)
它只是自定义dunder method __getattribute__
:自定义super
对象的所有属性检索,并尊重为超级对象创建的类的__mro__
。
这意味着:Python语言不需要实际从代理的类型继承来提供对其属性的访问。可以使用不同的机制完全自定义属性访问,这些机制将要代理的任何属性重定向到原始类。自定义__getattribute__
可能是更强大的"属性访问自定义,但也有__getattr__
或使用描述符。
所以,进一步回答 - 我对"鸭子打字的理解"是一个对象,该类提供了一组最小的属性和方法,看起来像"尝试像其他对象一样使用时的另一个对象。在这种观点下,可以说super
确实使用了duck typing,就像尝试从超级对象中检索方法和属性一样,这些将从代理类型中获取。
但是,super
类不会尝试模仿其repr
中的代理类型,或者以Python对象的常用方式进行检测(通过使用{{1}或者检查对象的dir
)。但是由于鸭子打字也不需要它,它只需要作为所需目的的原始对象,通常是获取并调用具有硬编码名称的方法。所以,是的,"鸭子打字"。
请注意,如果需要,Python自定义功能将允许" super"返回" True"来自代理课程的__dict__
来电。 (它没有,因为没有必要,如上所述)。