Python,调用__getattribute__返回的方法

时间:2017-06-19 17:15:54

标签: python methods metaprogramming

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

我有这个简单的python类:

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

尝试用不同的方法来获取方法:

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

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

问题是,如果我这样做:

b()
  

$您好!

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

a()
  

TypeError:' classmethod'对象不可调用

如何执行a方法?

1 个答案:

答案 0 :(得分:5)

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

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

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

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

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

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

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

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