代码之家  ›  专栏  ›  技术社区  ›  Dhruv

理解“包装描述符”本身的描述符协议

  •  0
  • Dhruv  · 技术社区  · 10 月前

    我试图探索如果我要访问“包装描述符”类本身的对象,描述符协议将如何工作。

    因此,我在中探索了c代码 typeobject.c 找到了两个 __get__ 功能- slot_tp_descr_get wrap_descr_get 。它们通过以下命令相互关联-

    TPSLOT(__get__, tp_descr_get, slot_tp_descr_get, wrap_descr_get,
               "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner.")
    

    这个 wrap_descr_get 是一个包装函数,用于包装 slot_tp_desc_get .

    通过代码 slot_tp_desc_get 我发现它叫 __得到__ self 争论。那么,如果传递了一个自己类型的对象,它会无限运行吗?在if语句之前的函数中有一个return语句,但我认为它不会运行。因为“if子句”检查类 自己 实施a __得到__ 或者没有,因为我们传递了这个类的一个对象,它会找到 __得到__ .


    相关问题

    如果我打电话给 __得到__ 其他类,如下面写的函数类。

    def fun():
        pass
    
    type(fun).__get__
    or
    fun.__get__
    

    是基础 __得到__ 直接调用的函数类 wrap_descr_get 或者根据描述符协议,该协议将查找 __得到__ (此处为包装描述符)并调用类的 __得到__ slot_tp_desc_get ?

    1 回复  |  直到 10 月前
        1
  •  1
  •   user2357112    10 月前

    wrap_descr_get 无法包裹 slot_tp_descr_get . slot_tp_desc_get 这只是一种可能的实现方式 tp_descr_get 插槽,而且从来都不是那个 wrap_descr_get 看到。

    A. slot_* 函数和包装描述符永远不会用于同一类型的同一插槽。


    插槽_* 当类型在Python中实现方法时,函数用于提供与Python方法对应的C槽实现。每个插槽对应一个Python方法。

    slot_tp_desc_get 是用于为以下对象提供C插槽实现的函数 tp_descr_get 当一个类实现时 __get__ 在Python中。这是进入 tp_descr_get 类的插槽如下:

    class Example:
        def __get__(self, instance, owner=None):
            ...
    

    当被呼叫时, slot_tp_desc_get 将查找 __得到__ 方法并调用它。


    包装描述符用于执行相反方向的包装。当一个类型直接实现C槽时,它们为与C槽对应的Python方法提供了一个实现。

    包装描述符是以下的实例 types.WrapperDescriptorType 。该类型在中实现 Objects/descrobject.c ,以及其他几种描述符类型。

    包装描述符需要一种方法,将传入的Python级调用转换为它们包装的任何插槽所采用的参数格式。对于包装一个 tp_descr_get 函数,它们翻译调用的方式是 wrap_descr_get .

    包装描述符类型也恰好有自己的 tp_descr_get 功能, wrapperdescr_get ,用于为包装描述符表示的任何方法生成绑定方法对象。这与包装器描述符包装的插槽是分开的,即使该插槽是 tp_descr_get 狭槽。


    因此,对于实现的类型 __得到__ 在Python中,C槽函数将被设置为 slot_tp_desc_get ,以及 slot_tp_desc_get 将委托给 __得到__ .对于实现的类型 tp_descr_get 在C中,将生成一个包装描述符来实现 __得到__ ,包装描述符将使用 wrap_descr_get 拨打电话 tp_descr_get .

    在任何情况下都不会 slot_tp_desc_get wrap_descr_get 最终递归地相互委派。