关于python:super()对象上的动态方法解析

Dynamic method resolution on a super() object

我需要按名称在super()对象上找到一个方法。这在使用"点运算符"表示法时有效:super(self.__class__,self).p。但是,我需要动态地这样做,比如super(self.__class__,self)["p"],它不起作用。

我尝试使用__getattr__,但是super对象没有这种方法。而super(self.__class__,self).__getattribute__("p")返回self.p而不是super().p

如何正确而优雅地做到这一点?

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A(object):
    def p (self):
        skip

class B(object):
    def p (self):
        skip

class AB (A,B):
    def p (self):
        skip

ab = AB()
o = super(ab.__class__, ab)

print dir(o)
print o.__getattribute__("p").__code__
print o.p.__code__

此代码输出:

1
2
3
4
['__class__', '__delattr__', '__doc__', '__format__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__
'
, '__self__', '__self_class__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__thisclass__']
<code object p at 000000000205f2b0, file"b.py", line 10>  # AB.p
<code object p at 0000000000361cb0, file"b.py", line 2>   # A.p


你要找的是getattr()。这工作:

1
2
>>> getattr(o,"p")
<bound method A.p of <__main__.AB object at 0x0000000000AA8160>>

直接使用__getattribute__()会丢失对对象的包装super()操作。您应该始终使用getattr()来获取方法或其他属性。一般来说,如果有其他选择,直接使用__dunder__方法是不可取的。