'Max Bachmann' via cython-users schrieb am 24.04.21 um 17:52:
> I have a lot of code which looks like this:
>
> ```
> var1 = malloc(...)
> try:
> var2 = malloc(...)
> try:
> do_something(var1, var2)
> finally:
> free(var2)
> finally:
> free(var1)
> ```
>
> It would be a lot simpler to write this as:
> ```
> with Manager(...) as var1, Manager(...) as var2:
> do_something(var1, var2)
> ```
>
> From my experiments it appears like I can write this manager in the
> following way:
>
> ```
> cdef class Manager:
> cdef type name
>
> def __cinit__(self, ...):
> name = malloc(...)
>
> cdef type __enter__(self):
> return
self.name
>
> def __exit__(self, type, value, tb):
> free(
self.name)
> ```
Looks good to me. (I'd probably use adifferent names for the class and its
attribute, e.g. "Malloc" and "data".)
> It was required to use `def __exit__` (but it appears like cython generates
> a C function for it) and `cdef type __enter__` so the type of the return
> value is known.
There is a slight overhead in the "__exit__" method because it takes three
Python object arguments, but it's not big.
It cannot currently be a cdef method because something needs to keep the
context manager object alive until the method is called. That could be
resolved differently, but that's how it currently is.
> However I wanted to double check whether this is actually the correct way
> to write this.
> I use this context manager in multiple files. Because of the `def`
> functions it appears like I can not place it in a pxd file and have to
> define it in each of the `pyx` files. Is this correct, or is there a way to
> define this once and import it from the other `pyx` files?
You can implement it in one pyx module, add a .pxd file to it that declares
and exports the context manager class, and then cimport it from other
modules. Those will then import the implementing module when they are
loaded and use the same class.
Stefan