2016-07-29 34 views
0

我似乎遇到的問題是,當我運行多次使用plusMinusAverage類的代碼(在我的情況下爲for循環)時,該類的新實例保留對之前創建的plustMinusAverage創建的pmaDicts列表的引用,並將其添加到最後。類中的字典的Python列表沒有像預期的那樣運行

含義 (代碼導致這進一步向下跌破)

things = [] 
for i in range(2): 
    thing[i] = plusMinusAverage(count3D=2) 
    print thing[i] 
    print thing[i].values3D 
>>> (plusMinusAverage at 0x00NSTUFF1) 
>>> [{"x":(attr.connection at 0x1234),"y":(attr.connection at 0x2345), etc..}, 
    {"x":(attr.connection at 0x3456),"y":(attr.connection at 0x4567), etc..}] 
>>> (plusMinusAverage at 0x00NSTUFF2) 
>>> [{"x":(attr.connection at 0x1234),"y":(attr.connection at 0x2345), etc..}, 
    {"x":(attr.connection at 0x3456),"y":(attr.connection at 0x4567), etc..}, 
    {"x":(attr.connection at 0x5678),"y":(attr.connection at 0x6789), etc..}, 
    {"x":(attr.connection at 0x7890),"y":(attr.connection at 0x8901), etc..}] 

什麼讓我這個是,它似乎打印出的對象,但隨後的名單似乎指向原來的,但與更多條目。我不明白爲什麼這份名單不會是唯一的。

對不起,大量發佈下面的代碼,但我認爲這個問題有足夠的細微差別,試圖做出更簡單的版本可能會邀請解決方案,這對我的情況不起作用,並且由於我不確定在哪裏問題完全在於,我將包括所有可能出錯的相關部分。 ..plus也許有人在maya中工作,可以使用它來構建自己的shaderNode工具。

class Tracker2(object): 
    dag = "" 
    obj = "" 
    getTime = "current" 

    def setPathing(self): 
     if self.nodeName == None: 
      self.nodeName = cmds.createNode('transform') 
      cmds.addAttr(self.nodeName, sn="type", ln="type", dt="string") 
      cmds.setAttr(self.nodeName + ".type", type="string", keyable=0) 
     sel = om.MSelectionList() 
     sel.add(self.nodeName) 
     self.obj = om.MObject() 
     self.dag = om.MDagPath() 
     sel.getDependNode(0, self.obj) 
     try: 
      sel.getDagPath(0, self.dag) 
     except: 
      pass 

    def __init__(self): 
     if not self.dag and not self.obj: 
      self.setPathing() 

    def fullpath(self): 
     if self.dag and self.dag.fullPathName(): 
      return self.dag.fullPathName() 
     return om.MFnDependencyNode(self.obj).name() 

class shaderNode(Tracker2): 
    def __init__(self): 
     self.nodeName = cmds.shadingNode(self.type,au=1) 
     Tracker2.__init__(self) 

class connection(object): 
    def __init__(self, attr, *args): 
     self.attr = attr 
    def __set__(self, instance, value): 
     if isinstance(value,basestring): 
      try: 
       cmds.connectAttr(value,instance.fullpath()+"."+self.attr,f=1) 
      except Exception as inst: 
       cmds.warning(inst) 
     elif not value: 
      temp = cmds.listConnections(instance.fullpath()+"."+self.attr,s=1,d=0) 
      if temp: 
       cmds.disconnectAttr(instance.fullpath()+"."+self.attr, temp[0]) 
     else: 
      cmds.warning("Set Connection: Source attribute is non-string value | "+value) 
    def __get__(self, instance, owner): 
     tempIn = cmds.listConnections(instance.fullpath()+"."+self.attr,s=1,d=0) 
     tempIn = tempIn if tempIn else [] 
     tempOut = cmds.listConnections(instance.fullpath()+"."+self.attr,s=0,d=1) 
     tempOut = tempOut if tempOut else [] 
     #returns list of [[incoming] , [outgoing]] 
     return [tempIn,tempOut] 

在單獨的PY文件,其中包含類連接加載與attr

class pmaDict(dict): 
    def __init__(self,instance,*args,**kwargs): 
     self.instance = instance 
     dict.__init__(self,*args,**kwargs) 
    def __getitem__(self, key): 
     thing = dict.__getitem__(self,key) 
     if key in self and isinstance(dict.__getitem__(self, key),attr.Attribute): 
      return thing.__get__(self.instance,None) 
     if key in self and isinstance(dict.__getitem__(self,key),attr.connection): 
      return thing.__get__(self.instance,None) 
     else: 
      return dict.__getitem__(self,key) 

    def __setitem__(self, key, value): 
     thing = dict.__getitem__(self,key) 
     if key in self and isinstance(dict.__getitem__(self,key),attr.Attribute): 
      thing.__set__(self.instance,value) 
     elif key in self and isinstance(dict.__getitem__(self,key),attr.connection): 
      thing.__set__(self.instance, value) 
     else: 
      dict.__setitem__(self,key,value) 

class plusMinusAvg(attr.shaderNode): 
    type = "plusMinusAverage" 
    values1D = [] 
    values2D = [] 
    values3D = [] 

    def addInput1D(self): 
     i = len(self.values1D) 
     print self 
     cmds.setAttr(self.fullpath() + ".input1D[" + str(i) + "]", 0) 
     newInput = pmaDict(self, 
          {"x": attr.Attribute("input1D[" + str(i) + "]", "float"), 
          "x_con": attr.connection("input1D[" + str(i) + "]")}) 
     self.values1D.append(newInput) 

    def addInput2D(self): 
     i = len(self.values2D) 
     print self 
     cmds.setAttr(self.fullpath() + ".input2D[" + str(i) + "]", 0, 0, type="double2") 
     newInput = pmaDict(self, 
          {"xy": attr.Attribute("input2D[" + str(i) + "]", "float"), 
          "x": attr.Attribute("input2D[" + str(i) + "].input2Dx", "float"), 
          "y": attr.Attribute("input2D[" + str(i) + "].input2Dy", "float"), 
          "xy_con": attr.connection("input2D[" + str(i) + "]"), 
          "x_con": attr.connection("input2D[" + str(i) + "].input2Dx"), 
          "y_con": attr.connection("input2D[" + str(i) + "].input2Dy")}) 
     self.values2D.append(newInput) 

    def addInput3D(self): 
     i = len(self.values3D) 
     print self 
     cmds.setAttr(self.fullpath()+".input3D["+str(i)+"]",0,0,0, type="double3") 
     newInput = pmaDict(self, 
          {"xyz": attr.Attribute("input3D["+str(i)+"]","double3"), 
          "x": attr.Attribute("input3D["+str(i)+"].input3Dx","float"), 
          "y": attr.Attribute("input3D["+str(i)+"].input3Dy","float"), 
          "z": attr.Attribute("input3D["+str(i)+"].input3Dz","float"), 
          "xyz_con": attr.connection("input3D["+str(i)+"]"), 
          "x_con": attr.connection("input3D["+str(i)+"].input3Dx"), 
          "y_con": attr.connection("input3D["+str(i)+"].input3Dy"), 
          "z_con": attr.connection("input3D["+str(i)+"].input3Dz")}) 
     self.values3D.append(newInput) 

    def __init__(self, count1D=0, count2D=0, count3D=0): 
     attr.shaderNode.__init__(self) 
     for i in range(count1D): 
      self.addInput1D() 
     for i in range(count2D): 
      self.addInput2D() 
     for i in range(count3D): 
      self.addInput3D() 
+1

你有* class屬性*;這些是每個類設置的,而不是每個實例,並且在這些實例之間共享。 –

+1

改爲在'__init__'方法中設置'self.values1D','self.values2D','self.values2D'。 –

+0

謝謝。這工作! –

回答

1

問題線就在這裏:

class plusMinusAvg(attr.shaderNode): 
    type = "plusMinusAverage" 
    values1D = [] 
    values2D = [] 
    values3D = [] 

要指定列表的類屬性。您通常習慣於這樣的任務,因爲如果您在方法調用中執行諸如values1d = blah之類的任務,則該任務將隱式地在self上進行。但是,您從不做另一項分配:您只需通過諸如append,__setitem__等方法使用類級別列表。因此,所有實例都使用在類對象中定義的相同列表。

要修復,移動三種列表分配到內__init__

self.values1D = [] 
self.values2D = [] 
self.values3D = [] 

這將確保每個實例都有它自己的名單。這樣做對於所有可變屬性(如列表和字典)作爲一般規則來避免將來出現相同類型的問題。

相關問題