2017-06-19 83 views
4

如果这个问题有一个重复的,对不起,我没有找到它,我会问如果有人这样的问题。Python,invoke方法返回__getattribute__

我有这个简单的Python类:

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

,并试图让不同的方法,我做的方法:

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

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

的问题是,如果我这样做:

b() 

$hi!

是回报,但是当我做:

a() 

TypeError: 'classmethod' object is not callable

我怎么能执行a方法?

+1

为什么你使用'对象.__ getattribute__'啊?这是错误的'__getattribute__'。 – user2357112

+0

@ user2357112我使用它,因为我想完全了解它是如何工作 –

回答

5

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

的解决方案是调用协议,如果有一个__get__ method本:

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

现在类方法结合到类,它再次工作:

>>> 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__实施。

+0

为什么第一个参数是无?我的意思是,我尝试了它,但它对我来说有点新,对不起,如果这个问题有一点基础知识 –

+0

那么,为什么'NothingSpecial .__ getattribute__'在'isinstance(NothingSpecial,type )'? –

+0

@DamianLattenero:第一个参数是针对*实例*的,但是这里有一个类,而不是一个实例。 –