2011-09-15 59 views
0

我的射線追蹤器的Python綁定中有幾個類實現了一個.transform()方法(Objects,Textures,Cameras等),它需要一個變換矩陣。我想讓所有這些類都實現.scale(),.rotate()等,並共享調用self.transform(...)的通用實現。一種方法是從一個提供這些方法及其實現的_Transformable類繼承。但是Cython的「擴展類型」不支持多重繼承,所以這對於已經繼承的類型不起作用。Cython中沒有繼承的方法實現

Cython不支持cdef類上的裝飾器,因此「@_transformable」裝飾器也不起作用。我認爲他們也不支持元類。有任何想法嗎?

如果方法可以從全局尺度()/ rotate()/ etc繼承其文檔字符串,則爲獎勵點。函數(返回matricies)。

編輯:下面是the file片段,讓發生了什麼事的指示:

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)) 

回答

0

你的變形很可能成爲一個do_everything。 組成是恕我直言,無論是在cython代碼和體系結構方面的答案。 查看:this article有一個很好的解釋。 IIRC,Blender使用這種架構,因此它看起來與您想要的完全兼容。 (順便說一下,你可以發佈一些代碼,所以我可以給你一個我腦海中的具體例子)。

很明顯,這取決於你的代碼庫的大小和你對它的控制。

+1

永久鏈接有拼寫錯誤;我提交了一個修改。 http://cowboyprogramming.com/2007/01/05/evolve-your-heirachy/ – forivall