2016-04-23 14 views
1

我正在嘗試重寫一個腳本,並且讓它很容易使用。基本上它是一個裝配腳本(就像銷燬的反面),您可以在其中輸入負載的變量,例如位置,位置是絕對還是相對,縮放,旋轉,可視性,隨機偏移等來創建動畫。第一個版本非常不友好,所以我試圖從一開始就很好地工作。我可以將變量分離到另一個類中,但保持相同的用法嗎?

我想過我該如何工作,並且設法保持清潔,但存在缺陷。正如你可以在下面看到的,它可以使用任何像SetGroup.frame[i].save()這樣的東西,我不想要(我不想在整個課堂上把if name is None的支票)。

這裏是我的代碼:

class SetGroup(object): 

    def __init__(self, name=None, _frame_only=False): 

     if name is None and not _frame_only: 
      raise TypeError('name of group must be provided') 

     self.selection = None 
     self.origin = None 

     self.start = None 
     self.end = None 
     self.offset = 0 
     self.distance = None 
     self.random = 0 

     self.location = None 
     self.rotation = None 
     self.scale = None 
     self.visibility = None 

     if not _frame_only: 
      self.frame = defaultdict(lambda: SetGroup(_frame_only=True)) 

    def save(self): 
     self.load() 
     #do a bit of error checking here 
     self.data[self.name] = {'ObjectSelection': self.selection, 
           'ObjectOrigin': self.origin, 
           'FrameStart': self.start, 
           'FrameEnd': self.end, 
           'FrameOffset': self.offset, 
           'FrameDistance': self.distance, 
           'FrameRandom': self.random, 
           'StartLocation': self.location, 
           'StartRotation': self.rotation, 
           'StartScale': self.scale, 
           'StartVisibility': self.visibility, 
           'ExtraFrames': self.frame} 
     pm.fileInfo['AssemblyScript'] = StoreData().save(self.data) 

    def load(self): 
     try: 
      self.data = StoreData().load(pm.fileInfo['AssemblyScript']) 
     except KeyError: 
      pm.fileInfo['AssemblyScript'] = StoreData().save({}) 

我想它的工作方式是這樣的:

a = SetGroup('test') 
a.location = ((0, 0, 0), True) 
a.start = 0 
a.end = 10 
a.frame[5].location = ((10, 10, 10), False) 
a.frame[5].scale = ((2, 1, 1), True) 
a.save() 

除非任何人都可以想辦法這將使其更我怎樣才能將location,rotation,scale,visibility分開成另一個類並再次鏈接起來,這樣它們仍然可以在類的核心層工作,但是也可以用於幀字典呢?

編輯 - 得到它的工作的基本層次:

class _MovementInfo(object): 
    def __init__(self, location=None, rotation=None, scale=None, visibility=None): 
     self.location = location 
     self.rotation = rotation 
     self.scale = scale 
     self.visibility = visibility 

    def __repr__(self): 
     return '_MovementInfo(location={x.location}, rotation={x.rotation}, scale={x.scale}, visibility={x.visibility}'.format(x=self) 

然後,我在主類中使用此合併的字典:

self.__dict__.update({k: v for k, v in _MovementInfo().__dict__.iteritems() if '__' not in k}) 
self.frame = defaultdict(_MovementInfo) 
+1

你熟悉的子類概念?你可以編寫一個你想要的所有基本行爲的類,然後用你想要的任何額外行爲創建一個子類,並且這個行爲也將具有原始行爲。 – Copperfield

+0

我見過有人使用'超級',但從來沒有讓我頭腦發熱。我記得'__dict__'包含了所有的值,所以我設法做了一些工作,我會用它更新這個問題,以防任何人有更好的方法:) – Peter

+1

粘貼原始代碼時是否錯過了一行?您從不在初始化程序中分配self.name。 –

回答

1

我會改變這樣的代碼:

class SetGroup(_Movement): 
    def __init__(self, name=None): 
     if name is None: 
      # ... 
     super().__init__() 
     # ... 
     self.random = 0 # __init__ should end here 

    # ... 

但是你應該檢查所有幀中的所有_MovementInfo都是_MovementInfo或從它們繼承(檢查此:isinstance(x, _MovementInfo)),但不是SetGroup的(檢查此:not isinstance(x, SetGroup))。

super()super(SetGroup, self)的簡稱(您必須使用python2的最後一個選項),它基本上是一個保存基類所有內容的對象,並允許您調用修改調用它的類的方法。

或者代碼:

class A(object): 
    def __init__(self, y): 
     self.x = 2 
     self.y = y 

class B(A): 
    def __init__(self, y, z): 
     super().__init__(y) # equivalent to: A.__init__(self, y) 
     self.z = z 

b = B(3, 4) 
# b's x is 2, b's y is 3 (both set by A.__init__, the last one was passed by B), and b's z is 4 (set by B.__init__) 

我希望這有助於,

CodenameLambda

+0

啊謝謝,所以這個,我保持'自我。frame = defaultdict(_MovementInfo)'並且失去'self .__ dict __。update'部分? – Peter

+0

我有點現在與您的更新問題,但它抱怨我不能有'超()'沒有參數(如果我複製並粘貼你的第二個例子相同的錯誤)。我在網上看到,也許'超級(_MovementInfo,self)'可以工作,但它沒有:P – Peter

+0

是的。這基本上是你應該做的。因爲'__dict__'是通過繼承來完成的,而這些框架只是一個包含'_MovementInfo'的字典。 – CodenameLambda

相關問題