何时何为有用的拥有描述符的`__get__`方法返回另一个描述符?

2024-07-04 08:54:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个容器,里面有一个对象的方法,可能还有一些描述符。我想通过检查描述符是否有一个'get'方法来测试描述符是否已经展开。令我惊讶的是,class方法的__get__方法返回的对象也有一个__get__方法。你知道这种行为什么时候有用吗?它是否与重写派生类中的类方法有关?你知道吗

import inspect

class K:    
    @classmethod
    def cm(cls, a, b, c):
        pass

def get_attr_info(attr):
    try:
        sig = inspect.signature(attr)
    except:
        sig = None

    attr_info = [
        ('id ', id(attr),),
        ('type  ', type(attr),),
        ('hasattr ', '__get__', hasattr(attr, '__get__'),),
        ('hasattr ', '__call__', hasattr(attr, '__call__'),),
        ('SIG:  ', sig,)
    ]
    return attr_info

get_label = lambda tpl: ' '.join([str(x) for x in tpl[0:-1]]).ljust(20)

kinst = K()
cm = object.__getattribute__(type(kinst), '__dict__')['cm']

try:
    for idx in range(0, 5):
        info = get_attr_info(cm)        
        print('\n' + '\n'.join([get_label(tpl) + str(tpl[-1]) for tpl in info]))
        cm = cm.__get__(kinst, type(kinst))
except AttributeError:
    print(idx)

输出为:

id                  44545808
type                <class 'classmethod'>
hasattr  __get__    True
hasattr  __call__   False
SIG:                None

id                  6437832
type                <class 'method'>
hasattr  __get__    True
hasattr  __call__   True
SIG:                (a, b, c)

id                  6437832
type                <class 'method'>
hasattr  __get__    True
hasattr  __call__   True
SIG:                (a, b, c)

id                  6437832
type                <class 'method'>
hasattr  __get__    True
hasattr  __call__   True
SIG:                (a, b, c)

id                  6437832
type                <class 'method'>
hasattr  __get__    True
hasattr  __call__   True
SIG:                (a, b, c)

Tags: 方法infoidtruegettypecmcall
1条回答
网友
1楼 · 发布于 2024-07-04 08:54:19

由于未绑定的方法对象,您看到的特定行为是有意义的。回到Python2,如果你这么做了

class Foo(object):
    def useful_method(self):
        do_stuff()

class Bar(object):
    useful_method = Foo.useful_method

Foo.useful_method将计算为未绑定方法对象,类似于函数,但与函数略有不同。未绑定的方法对象需要一个__get__,因此Bar().useful_method会自动绑定self,就像Foo.useful_methodBar的定义期间对函数而不是未绑定的方法求值一样。你知道吗

未绑定方法对象和绑定方法对象是用相同的类型实现的,因此绑定方法共享未绑定方法所拥有的相同的__get__方法。不过,对于绑定方法对象,__get__只返回绑定方法对象,就好像不涉及描述符逻辑一样。你知道吗

现在没有绑定的方法了,method对象的__get__方法是多余的,但是它还没有被删除。你知道吗

相关问题 更多 >

    热门问题