什么是python中的'slot wrapper'?

时间:2014-07-11 23:53:47

标签: python

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__)

3 个答案:

答案 0 :(得分:3)

这是一个内部类型,用于一些callables,内置类的方法。它与函数或任何其他可调用函数不同的原因并不重要。您可以将它作为对象上的方法调用它。

答案 1 :(得分:2)

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 :(得分:0)

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

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

因此,它们实际上是包装由C实现的对象方法的方法。 Python中的许多魔术方法和属性都是通过C对象上的插槽包装器实现的。由于大多数Python实现都是用C编写的,因此很有意义。