1

我试图通过使用变量方法名称来调用超类的方法。通常,我会看到以下两行代码是等效的:

someObj.method()
someObj.__getattribute__( 'method' )()

事实上,我相信,这也是我使用第一行时实际发生的情况。然而,在下面的例子中,第二行产生了一个奇怪的问题。

super用来构造一个超对象并调用超类的方法。直接执行它按预期工作,但是使用__getattribute__首先获取方法会导致无限循环,它会一次又一次地调用子类的方法。

请参阅以下代码:

class A:
    def example ( self ):
        print( 'example in A' )

class B ( A ):
    def example ( self ):
        print( super( B, self ).example )
        print( super( B, self ).__getattribute__( 'example' ) )
        super( B, self ).example()
        #super( B, self ).__getattribute__( 'example' )()

        print( 'example in B' )

x = B()
x.example()

如果您运行该代码,一切都会按预期进行,并且您应该得到类似于以下内容的输出:

<bound method B.example of <__main__.B object at 0x01CF6C90>>
<bound method B.example of <__main__.B object at 0x01CF6C90>>
example in A
example in B

所以这两种方法,一种是直接访问,另一种是 via __getattribute__,看起来是一样的。但是,如果您用注释掉的行替换方法调用,您最终会遇到递归运行时错误。

为什么会发生这种情况,更重要的是,当我使用工作行时,如何以与 python 内部相同的方式实际访问该方法?

编辑

当我以为我已经尝试了所有方法时,我发现这是可行的:

super.__getattribute__( super( B, self ), 'example' )()

它实际上等于super( B, self ).example

4

2 回答 2

5

不要用于__getattribute__这个:它不会做你认为它做的事情。(它是 Python 机器的一个专门部分,主要用于实现新的属性访问魔法。)

对于正常的属性访问,使用getattr//内置setattrdelattr

self.example           == getattr(self, 'example')
super(B, self).example == getattr(super(B, self), 'example')

(如果您想了解__getattribute__它的作用,请阅读描述符操作指南和 Python数据模型参考。)

于 2010-10-03T02:21:09.447 回答
0

获取对象的example属性会生成B的绑定副本B.example。调用它会导致递归错误。你打电话A.__getattribute__()是无关紧要的;你还有一个B对象。

于 2010-10-02T23:31:43.360 回答