在C#中我会去:
myObj.base
我有一个继承自date.datetime的Date类。 Date类会覆盖__gt__()
和__lt__()
,因此在使用<
和>
运算符时会调用它们。我不想使用这些覆盖 - 我想在Date实例上使用date.datetime方法。
答案 0 :(得分:6)
使用super()
获取超类对象。在Python命令提示符下键入help(super)
。
从手册:
class super(object)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
| Typical use to call a cooperative superclass method:
| class C(B):
| def meth(self, arg):
| super(C, self).meth(arg)
答案 1 :(得分:3)
如果我理解你的问题,这在Python中没有意义。在子类的实例中没有“基本实例”。
Python实例只是一件事,包含一组属性(任何属性都可能由其任何基类设置/修改,或者实际上是根据其任何类之外的代码设置/修改)。实际上,可以在运行时更改实例的类,甚至可以将其移植到完全不同的继承层(这通常不是一个好主意,但它定义明确)。无论如何,实例仍然是一个单一的单一对象,它只知道它具有什么属性以及它是哪个类的实例(实际上它只是一个属性:__class__
)。
编辑:如果你想要的是能够在一个实例上调用重写的方法,那么你可以使用super
来做到这一点,as hocl回答。但是,从你的评论中可以看出,你并没有完全了解super
正在做什么(这很自然,因为它非常复杂)。
super(Date, myObj)
不返回“基础datetime.date
”实例,因为没有这样的东西,只有myObj
对象。虽然为了您的目的,听起来这将满足您的需求(你可以停止在这句话)。
它的作用是返回myObj
周围的神奇包装,查找从“Date
后面开始的方法;即如果Date
没有覆盖它,它会找到将被调用的方法。所以在这个的情况下,它会找到datetime.date
中的所有方法,因为你只有单继承。
一个关键的区别是它支持多重继承。如果有人创建了另一个继承自Date
的类并且还从另一个路径继承datetime.date
,那么super(Date, instanceOfThatClass)
可能实际上不会点击datetime.date
的方法。这取决于继承heirarchy的细节。实际上,这是super
设计的情况;它使复杂的多继承层次结构中的类能够协同调用彼此的实现,确保每个只调用一次,并且按照合理的顺序调用(尽管它可能不是每个终极叶类的相同顺序,所以中间的类层次结构实际上不知道他们正在调用哪个超类实现)。我的理解是C#中不会出现这种复杂情况,因此它可以提供简单的.base
语法。
我的理解也是(这是一个猜测),因为C#是静态类型的并且支持继承自预编译库中定义的类,当你从类Sub
继承时{1}},在Base
的实例中,确实有一个完整的Sub
实例,您可以在其中调用方法然后调用方法。这会影响阴影场;我希望(再次,作为非C#程序员猜测一下)从Base
实例获取Base
实例后,对字段的任何直接引用都会被覆盖Sub
会从Sub
点击该字段,而不是来自Base
的字段。
在Python,OTOH中,没有基本实例,类不能覆盖字段。如果Sub
和Date
的构造函数和方法都引用相同的字段,那么它们只是实例中的一个字段,它们都是共享的。因此,如果您将其视为获取基本实例,则使用datetime.date
将不会更改您将访问的字段。
鉴于您没有使用复杂的多重继承情况,如果您想要一个简单的语法,您实际上可以直接调用super
,虽然它看起来很难看,因为您在使用时不会使用中缀运算符语法你这样做。如果你考虑普通的方法,那就不那么可怕了;在这种情况下,它可能比使用Date.__lt__(myObj, otherObj)
更简单。
回家留言:我非常确定super
就是你想要的。但是如果你遇到更复杂的情况,你不希望将super(Date, myObj)
视为获得“基本实例”的方式,就像你在C#中那样。这种理解会在多重继承中引起你的兴趣(无论如何都会让人感到混乱),但是当你使用相同的字段在继承层次结构中有多个层时也是如此。