Совместное использование реализаций метода в Cython без наследования - PullRequest
0 голосов
/ 16 сентября 2011

У меня есть несколько классов в привязке Python моего ray tracer, которые реализуют метод .transform () (Objects, Textures, Cameras и т. Д.), Который принимает матрицу преобразования. Мне бы хотелось, чтобы все эти классы также реализовывали .scale (), .rotate () и т. Д. И имели общие реализации, которые вызывают self.transform (...). Один из способов сделать это - наследовать от класса _Transformable, который предоставляет эти методы и их реализации. Но «расширения типов» Cython не поддерживают множественное наследование, поэтому это не работает для типов, которые уже наследуют.

Cython также не поддерживает декораторы в классах cdef, поэтому декоратор "@_transformable" также не будет работать. И я не думаю, что они также поддерживают метаклассы. Есть идеи?

Бонусные баллы, если методы могут наследовать свои строки документов из глобального масштаба () / rotate () / и т. Д. функции (которые возвращают матрицы).

РЕДАКТИРОВАТЬ: Вот фрагмент файла , который дает представление о том, что происходит:

def translate(*args, **kwargs):
  """
  Return a translation.

  Accepts the same arguments that Vector(...) does.
  """
  return _Matrix(dmnsn_translation_matrix(Vector(*args, **kwargs)._v))

cdef class Pigment:
  """Object surface coloring."""
  cdef dmnsn_pigment *_pigment

  # ...

  def transform(self, Matrix trans not None):
    """Transform a pigment."""
    self._pigment.trans = dmnsn_matrix_mul(trans._m, self._pigment.trans)
    return self

Решение по наследованию будет выглядеть так:

cdef class _Transformable:
  def scale(self, *args, **kwargs):
    return self.transform(scale(*args, **kwargs))
  def translate(self, *args, **kwargs):
    return self.transform(translate(*args, **kwargs))
  def rotate(self, *args, **kwargs):
    return self.transform(rotate(*args, **kwargs))

1 Ответ

0 голосов
/ 16 сентября 2011

Ваш трансформируемый, вероятно, станет do_everything. Композиция является ИМХО и ответом с точки зрения кода и архитектуры Cython. см. эту статью для хорошего объяснения. IIRC, Blender используют эту архитектуру, поэтому она выглядит вполне совместимой с тем, что вы хотите сделать. (Кстати, не могли бы вы опубликовать немного кода, чтобы я мог дать вам конкретный пример того, что я имею в виду).

Очевидно, это зависит от размера вашей кодовой базы и вашего контроля над ней.

...