[pyar] "engañando" a isinstance

Hernan Grecco hernan.grecco en gmail.com
Jue Ago 15 16:55:44 ART 2013


Hola,

Tengo un problema relacionado con numpy, pero engloba una pregunta mas
general. Como hacer que una clase parezca derivar de otra sin hacerlo?

Les cuento el problema (los que no saben de numpy, perdon por lo especifico):

Tengo una clase que envuelve un array de numpy. La clase define todas
las operaciones matemáticas y tiene un valor de __array_priority__
alto de forma tal que toma el control para todo las ufunc

class Quantity(object):

    __array_priority__ = 17

    def __init__(self, value):
        self.value = value

    def __add__(self, other):
         # etc
     # etc

Si hago lo siguiente:
>>> import numpy as np
>>> arr = np.ones((3,3))
>>> q = Quantity(2 * np.ones((3,3)))

Tanto si hago `arr + q`, como si hago `q + arr`, `Quantity.__add__` es
llamado como queria. Esto es porque numpy internamente llama a la
funcion del objeto con el mayor __array_priority__.

Ahora si hago,
>>> mat = np.matrix((3, 3))
>>> mar = np.ma.masked_array(np.ones((3,3)))

Cuando `q` opera con `mat` or `mar` (independientemente del orden), se
llama al metodo de la otra clase. En este caso no se respeta
`__array_priority__` porque es un tipo especial de array. Mirando
dentro del codigo de numpy, vi que se usa isinstance()

La unica solucion que encontré (gracias a la gente de stack overflow)
es definir mi clase asi:

class Quantity(np.matrixlib.defmatrix.matrix, np.ma.core.MaskedArray,
np.ndarray):
    # etc

pero esto me molesta bastante por razones que no viene al caso.
Quiero, envolver un array de numpy no derivar de el.

Pense en "engañar" a isinstance usando `abc.ABCMeta` y
`__subclasshook__`  pero sin exito. Alguna idea de como resolver esto
de esta o alguna otra forma?

Gracias,

Hernan


More information about the pyar mailing list