Python,调用 __getattribute__ 返回的方法

Python, invoke method returned by __getattribute__

如果这个问题重复了,对不起,我没有找到,如果有人找到我会删除这个问题。

我有这个简单的 python class:

class NothingSpecial:
     @classmethod
     def meth(cls): 
          print("hi!")

并尝试用不同的方式获取方法:

a = (object.__getattribute__(NothingSpecial, 'meth'))

b = (getattr(NothingSpecial, 'meth'))

问题是,如果我这样做:

b()

$hi!

是return,但当我这样做时:

a()

TypeError: 'classmethod' object is not callable

如何执行 a 方法?

您正在绕过 descriptor protocol,并且您有一个未绑定的 class 方法。

解决方案是调用协议,如果存在 __get__ method

if hasattr(a, '__get__'):
    a = a.__get__(None, NothingSpecial)
a()

现在 class 方法绑定到 class 并且它再次工作:

>>> a.__get__(None, NothingSpecial)
<bound method NothingSpecial.meth of <class '__main__.NothingSpecial'>>
>>> a.__get__(None, NothingSpecial)()
hi!

或者,使用 正确的 __getattribute__,它实际上知道如何将描述符协议应用于 class 属性; classes 不使用 object.__getattribute__,而是 type.__getattribute__:

>>> type.__getattribute__(NothingSpecial, 'meth')
<bound method NothingSpecial.meth of <class '__main__.NothingSpecial'>>

您实际上想要访问 type(NothingSpecial).__getattribute__ 以允许元classes 在这里覆盖 __getattribute__ 的实现。