预定义描述符在函数中如何工作?

7 投票
1 回答
700 浏览
提问于 2025-04-17 15:25

Python中的函数有一个叫做描述符的特性。我觉得在大多数情况下我不应该直接使用这个特性,但我想知道它是怎么工作的。我尝试了一些操作,涉及到这样的对象:

  1.  

    def a():
        return 'x' 
    
    a.__get__.__doc__
    'descr.__get__(obj[, type]) -> value'
    

    这里的obj是什么?它的类型是什么?

  2.  

    >>> a.__get__()
    TypeError:  expected at least 1 arguments, got 0
    
    >>> a.__get__('s')
    <bound method ?.a of 's'>
    
    >>> a.__get__('s')()
    TypeError: a() takes no arguments (1 given)
    

    我确定我不能对那些不需要参数的函数使用这个技巧。是不是说只有在调用带参数的函数时才需要这样做?

  3.  

    >>> def d(arg1, arg2, arg3):
            return arg1, arg2, arg3
    >>> d.__get__('s')('x', 'a')
    ('s', 'x', 'a')
    

    为什么第一个参数是直接通过__get__获取的,而其他的参数则是通过返回的对象获取的呢?

1 个回答

9

a.__get__ 是一种将函数和对象“绑定”在一起的方法。也就是说:

class C(object):
    pass

def a(s):
    return 12

a = a.__get__(C)

大致相当于

class C(object):
    def a(self):
        return 12

(不过这样做并不是个好主意。因为这样的话,C 并不知道它有一个叫 a 的绑定方法,你可以通过执行 dir(C) 来确认这一点。简单来说,__get__ 只是绑定过程中的一部分。)

这就是为什么你不能对一个不接受任何参数的函数这样做——它必须接受第一个参数(通常是 self),这个参数代表具体的实例。

撰写回答