【问题标题】:What is a 'slot wrapper' in python?什么是 python 中的“插槽包装器”?
【发布时间】:2020-10-15 15:08:52
【问题描述】:

object.__dict__ 和其他地方的隐藏方法设置如下:

 <dictproxy {'__add__': <slot wrapper '__add__' of 'instance' objects>,
 '__and__': <slot wrapper '__and__' of 'instance' objects>,
 '__call__': <slot wrapper '__call__' of 'instance' objects>,
 '__cmp__': <slot wrapper '__cmp__' of 'instance' objects>,
 '__coerce__': <slot wrapper '__coerce__' of 'instance' objects>,
 '__contains__': <slot wrapper '__contains__' of 'instance' objects>,
 '__delattr__': <slot wrapper '__delattr__' of 'instance' objects>,
 '__delitem__': <slot wrapper '__delitem__' of 'instance' objects>,
 '__delslice__': <slot wrapper '__delslice__' of 'instance' objects>,
 '__div__': <slot wrapper '__div__' of 'instance' objects>,
 '__divmod__': <slot wrapper '__divmod__' of 'instance' objects>,
 ...

这些是什么,它们的用途是什么?

编辑: 这是来自:

class A:
    pass
b = A()
print(type(b).__dict__)

【问题讨论】:

  • 我认为您无效地缩短了表示。这是mappingproxy({…})。对于正确的答案,这可能会有所不同。
  • 谢谢。我看到的那个说
  • 有一个答案here 可能会对此有所了解。

标签: python


【解决方案1】:

object 类,因为它是类层次结构的基类。我们当然可以推断出它的底层代码是为了表现良好而编写的。

在 CPython 中,python 的实现是用 C 和 Python 编写的。底层代码用 C 语言编写,以满足性能需求。

但是,如何从 python 脚本调用驻留在某些 C 编译的二进制文件中的函数指针来管理和处理??

例如,显然调用repr(b) 将遵循以下逻辑:

  1. 检查绑定方法的名称__repr__ 是否存在于b.__dict__ 中,然后尝试调用它。
  2. 如果未找到,请在其类下搜索名称type(b).__dict__,相当于A.__dict__
  3. 如果未找到,则会在其超类下进行搜索。 A.__base__,在我们的例子中是 object 类。并且由于 hasattr(object, '__repr__')==True 将通过返回绑定方法 object.__repr__ 来完成查找,该方法是一个插槽包装器,是类 wrapper_descriptor 的一个实例。
  4. 然后包装器会处理必要的事情(获取有关对象 b 的详细信息、获取指向 C 函数的指针、传递必要的参数、处理异常和错误...)。

所以它几乎是一个包装器,它使用 CPython 自己的内置 API 来为我们省去头疼的问题,并将两种语言的逻辑分开。

显示两次相同调用的最终示例:

>>> object.__repr__(b)
'<__main__.A object at 0x011EE5C8>'
>>> repr(b)
'<__main__.A object at 0x011EE5C8>'

【讨论】:

    【解决方案2】:

    根据https://doc.sagemath.org/html/en/reference/cpython/sage/cpython/wrapperdescr.html

    插槽包装器安装在扩展类型的字典中,以访问在 C 中实现的特殊方法。例如,object.__init__ 或 Integer.__lt__。请注意,插槽包装器始终是未绑定的(有一个绑定变体称为 method-wrapper)。

    因此,它们实际上是封装了 C 实现的对象方法的方法。 Python 中的许多神奇方法和属性都是通过 C 对象上的插槽包装器实现的。由于 Python 的大多数实现都是用 C 编写的,因此这是有道理的。

    【讨论】:

      【解决方案3】:

      它是一种用于某些可调用对象、内置类方法的内部类型。为什么它与函数或任何其他可调用对象不同并不重要。您可以将其作为对象上的方法调用。

      【讨论】:

      • 虽然技术上是正确的,但 以上都没有真正回答手头的问题。您可能至少已经链接到 driaxauthoritative answer 关于这个主题,其中确实确实回答了这个问题。 &lt;/sigh&gt;
      • 随意添加另一个答案&lt;/exasperated-gesture&gt;
      猜你喜欢
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      • 2015-09-03
      • 1970-01-01
      • 2018-10-01
      • 2014-03-05
      • 2012-02-27
      • 2020-10-05
      相关资源
      最近更新 更多