Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a 'slot wrapper' in python?

Tags:

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__)
like image 855
pjc Avatar asked Jul 11 '14 23:07

pjc


2 Answers

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>'
like image 177
Pixel_teK Avatar answered Nov 10 '22 02:11

Pixel_teK


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.

like image 1
James Hannock Avatar answered Nov 10 '22 03:11

James Hannock