2014-01-08 68 views
3

我有一个关于python super()的问题。python超级执行父级方法

这里是我的代码

class A(object): 
    def test(self): 
     t = [self.__class__.__name__] 
     return t 

class B(A): 
    def test(self): 
     t = super(B, self).test() 
     t.append(self.__class__.__name__) 
     return t 

B().test() 

结果是[B,B]

,但我想[A,B]

可能获得[A,B] ?

谢谢大家!

回答

3

您可以使用该类的__mro__属性。

>>> class A(object): 
...  def test(self): 
...   return [c.__name__ for c in type(self).__mro__[-2::-1]] 
... 
>>> class B(A): 
...  pass 
... 
>>> B().test() 
['A', 'B'] 
>>> A().test() 
['A'] 

>>> B.__mro__ 
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>) 
>>> B.__mro__[::-1] 
(<type 'object'>, <class '__main__.A'>, <class '__main__.B'>) 
>>> B.__mro__[-2::-1] 
(<class '__main__.A'>, <class '__main__.B'>) 
+0

哇...很好的答案。顺便说一句,为什么我不能通过'print dir(B)'看到'__mro__'属性,但是'print B .__ mro__'确实提供了你提到的信息。 – WKPlus

+0

@WKPlus,[**内置类型 - 特殊属性**](http://docs.python.org/2/library/stdtypes.html?highlight=__mro__#class.__mro__)明确指出:实现将几个特殊的只读属性添加到几个相关的对象类型中。其中一些不是由'dir()'内置函数报告的。 – falsetru

0

这是否会帮助你:

class A(object): 
    def test(self): 
     t = [A.__name__] 
     return t 

class B(A): 
    def test(self): 
     t = super(B, self).test() 
     t.append(B.__name__) 
     return t 

B().test() 

我想你想的类的名称,而不是实例类。

0

只是觉得应该是相反的加入明显的期望,做

super(B, self).func() 

其中A是超不创建A级,然后调用该函数。它只是在名字空间A中找到函数,并在当前类中调用它。由于对象没有改变,引用self.__class__仍然指向类别B,并且self.__class__.__name__仍然是名称B

事实上,如果你有这样的事情

class A(object): 
    def func(self, somearg): 
     pass 

class B(A): 
    def anotherfunc(self, someotherarg): 
     super(B, self).func(someotherarg) 
     self.func(someotherarg) 

最后两个语句实际上是相同的......当你调用一个函数,蟒蛇看起来通过MRO在比赛最接近的功能。因为B实际上并没有一个叫func的函数,所以它会在A中选择一个。

此外,作为第二个答案,你可以显式调用__name__通过类的方法(通过类AB直接),而不是通过实例......将始终引用同一个类,无论它在哪里叫从。