Python,调用__getattribute__返回的方法

Dam*_*ero 4 python methods metaprogramming

如果这个问题有重复,抱歉,我没有找到它,如果有人这样做,我会提出问题.

我有这个简单的python类:

class NothingSpecial:
     @classmethod
     def meth(cls): 
          print("hi!")
Run Code Online (Sandbox Code Playgroud)

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

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

b = (getattr(NothingSpecial, 'meth'))
Run Code Online (Sandbox Code Playgroud)

问题是,如果我这样做:

b()
Run Code Online (Sandbox Code Playgroud)

$嗨!

是回归,但是当我这样做时:

a()
Run Code Online (Sandbox Code Playgroud)

TypeError:'classmethod'对象不可调用

我该如何执行该a方法?

Mar*_*ers 5

您绕过了描述符协议,并且您有一个未绑定的类方法.

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

if hasattr(a, '__get__'):
    a = a.__get__(None, NothingSpecial)
a()
Run Code Online (Sandbox Code Playgroud)

现在classmethod绑定到类,它再次工作:

>>> a.__get__(None, NothingSpecial)
<bound method NothingSpecial.meth of <class '__main__.NothingSpecial'>>
>>> a.__get__(None, NothingSpecial)()
hi!
Run Code Online (Sandbox Code Playgroud)

或者,使用正确的 __getattribute__,实际知道如何将描述符协议应用于类属性的那个; 类不使用object.__getattribute__,但是type.__getattribute__:

>>> type.__getattribute__(NothingSpecial, 'meth')
<bound method NothingSpecial.meth of <class '__main__.NothingSpecial'>>
Run Code Online (Sandbox Code Playgroud)

您实际上想要访问type(NothingSpecial).__getattribute__以允许元类覆盖__getattribute__此处的实现.