es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Utilice el cierre en PyGetSetDef para reutilizar los getter-setter de atributos.

Como sugiere el título, estoy tratando de crear varias atributos, pero el código se está volviendo repetitivo y desordenado. Quiero usar el argumento de cierre para hacer que el código sea más compacto.

Según la referencia de la API de C, el cierre es un puntero a una función que proporciona información adicional para los getters/setters. No he podido encontrar un ejemplo de su uso.

Así es como lo estoy usando actualmente:

Código:

static void closure_1() {};
static void closure_2() {};

static PyObject *
FOO_getter(FOO* self, void closure) {
if (closure == &closure_1) {
return self->bar_1;
} else if (closure == &closure_2) {
return self->bar_2;
}
}
static int
FOO_setter(FOO
self, PyObject value, void *closure) {
if (closure == &closure_1) {
if (algún valor es inválido) {
PyErr_SetString(PyExc_ValueError, “valor inválido para bar_1.”);
return -1;
}
} else if (closure == closure_2) {
if (algún valor es inválido) {
PyErr_SetString(PyExc_ValueError, “valor inválido para bar_2.”);
return -1;
}
}
return 0;
}
static PyGetSetDef FOO_getsetters[] = {
{“bar_1”, (getter) FOO_getter, (setter) FOO_setter, “atributo bar_1”, closure_1},
{“bar_2”, (getter) FOO_getter, (setter) FOO_setter, “atributo bar_2”, closure_2},
{NULL} /
Centinela */
};

Funciona como quiero, pero parece más como un truco que como algo “pythonico”. ¿Hay una mejor manera de manejar esto? Por ejemplo, llamar al cierre de alguna manera.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, puede usar el argumento closure para hacer que el código sea más compacto. En lugar de tener funciones getter y setter separadas para cada atributo, puede usar una única función y el argumento closure para diferenciar entre los atributos.

    Por ejemplo, puede definir una única función getter y setter de esta forma:

    static PyObject *
    FOO<em>getter(FOO* self, void *closure) 
        if (closure == &closure</em>1) 
            return self->bar<em>1;
         else if (closure == &closure</em>2) 
            return self->bar_2;
    
    static int
    FOO<em>setter(FOO* self, PyObject *value, void *closure) 
        if (closure == &closure</em>1) 
            if (de alguna manera el valor es inválido) 
                PyErr<em>SetString(PyExc</em>ValueError, "valor inválido para bar_1.");
                return -1;
    
    <pre><code> else if (closure == closure_2) 
        if (de alguna manera el valor es inválido) 
            PyErr_SetString(PyExc_ValueError, &quot;valor inválido para bar_2.&quot;);
            return -1;
    
    return 0;
    </code></pre>
    
    <code>
    Luego, puede usar el argumento `closure` para diferenciar entre los atributos en la matriz `PyGetSetDef`:
    </code>c
    
    static PyGetSetDef FOO<em>getsetters[] = 
        "bar</em>1", (getter) FOO<em>getter, (setter) FOO</em>setter, "atributo bar<em>1", closure</em>1,
        "bar<em>2", (getter) FOO</em>getter, (setter) FOO<em>setter, "atributo bar</em>2", closure_2,
        NULL  /* Sentinel */
    ;
    
    

    De esta manera, puede usar las mismas funciones getter y setter para todos los atributos, y el argumento closure proporcionará la información necesaria para diferenciarlos.

Comments are closed.