Архитектура для обеспечения различных серверных частей линейной алгебры

Я создаю прототип новой системы на Python; функциональность в основном числовая.

Важным требованием является возможность использовать различные серверные части линейной алгебры: от индивидуальных пользовательских реализаций до общих библиотек, таких как Numpy. Реализация линейной алгебры (то есть серверная часть) должна быть независимой от интерфейса.

Моя первоначальная архитектурная попытка такова:

(1) Определить системный интерфейс

>>> v1 = Vector([1,2,3])
>>> v2 = Vector([4,5,6])
>>> print v1 * v2
>>> # prints "Vector([4, 10, 18])"

(2) Реализовать код позволяя использовать этот интерфейс независимо от серверной части

# this example uses numpy as the back-end, but I mean
# to do this for a general back-end
import numpy 
def numpy_array(*args): # creates a numpy array from the arguments
    return numpy.array(*args)

class VectorBase(type):
    def __init__(cls, name, bases, attrs):
        engine = attrs.pop("engine", None)
        if not engine:
            raise RuntimeError("you need to specify an engine")
        # this implementation would change depending on `engine`
        def new(cls, *args):
            return numpy_array(*args)   
        setattr(cls, "new", classmethod(new))

class Vector(object):   
    __metaclass__ = VectorBase        
    # I could change this at run time
    # and offer alternative back-ends
    engine = "numpy"  
    @classmethod
    def create(cls, v):
        nv = cls()
        nv._v = v
        return nv    
    def __init__(self, *args):  
        self._v = None
        if args:
            self._v = self.new(*args)
    def __repr__(self):
        l = [item for item in self._v]
        return "Vector(%s)" % repr(l)
    def __mul__(self, other):
        try:
            return Vector.create(self._v * other._v)
        except AttributeError:
            return Vector.create(self._v * other)
    def __rmul__(self, other):
        return self.__mul__(other)

Этот простой пример работает следующим образом: класс Vector хранит ссылку на экземпляр вектора, созданный серверной частью ( numpy. ndarray в примере); все арифметические вызовы реализуются интерфейсом, но их оценка откладывается серверной части.

На практике интерфейс перегружает все соответствующие операторы и перекладывает ее на серверную часть (пример показывает только __ mul __ и __ rmul __ , но вы можете следить, что то же самое будет сделано для каждой операции).

Я хочу потерять некоторую производительность в обмен на настраиваемость. Несмотря на то, что мой пример работает, он кажется неправильным - я бы навредил серверной части из-за такого количества вызовов конструкторов! Это требует другой реализации метакласса , позволяющей лучше отложить вызовы.

Итак, как бы вы порекомендовали мне реализовать эту функцию? Я должен подчеркнуть важность сохранения всей системы » s Экземпляры вектора однородны и не зависят от серверной части линейной алгебры.

13
задан Escualo 19 March 2011 в 21:54
поделиться