简体   繁体   中英

What is a 'slot wrapper' in python?

object.__dict__ and other places have their hidden methods set to things like this:

 <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>,
 ...

What are these, and what are they used for?

Edit: This is the output from:

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

The object class, since it's the base class of the class hierarchy. One can certainly infer that its underlying code is written to perform well.

In the CPython, the implementation of python is written in C and Python. The underlying code is written in C to satisfy the need for performance.

But then How is a call from a python script toward a function pointer that resides in some C compiled binary file managed and handled ??

Apparently a call to repr(b) for example would follow the following logic :

  1. Check if for the bound method's name __repr__ exists in b.__dict__ then try to call it.
  2. If not found, search for the name under its class type(b).__dict__ the equivalent to A.__dict__ .
  3. If not found, then it would search under its Superclasses. A.__base__ , in our case that's the class object . and since hasattr(object, '__repr__')==True The lookup would finish by returning the bound method object.__repr__ , which is a slot wrapper that is an instance of the class wrapper_descriptor .
  4. The wrapper would then take care of the necessary stuff (getting details about the object b, getting the pointer to the C function, passing the necessary arguments, handling exceptions and errors ...) .

So it s pretty much a wrapper which uses the CPython's own API for builtins to save us the headache, and separate between the two languages' logic.

A Final Example Showing the same call twice :

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

According to https://doc.sagemath.org/html/en/reference/cpython/sage/cpython/wrapperdescr.html :

A slot wrapper is installed in the dict of an extension type to access a special method implemented in C. For example, object.__init__ or Integer.__lt__. Note that slot wrappers are always unbound (there is a bound variant called method-wrapper).

So, they are actually methods which wrap over C-implemented methods of objects. Many of the magic methods and attributes in Python are implemented via slot wrappers over C objects. As most implementations of Python are written in C, this makes sense.

It's an internal type used for some callables, methods on built-in classes. It doesn't really matter why it is different than a function, or any other callable. You can invoke it as a method on the object just the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM