2017-04-05 40 views
1

我想要做這樣的事情,Maya Python單行類實例和類變量賦值?

things = [ node().path = x for x in cmds.ls(sl=1,l=1)] 

,但我發現一個無效的語法錯誤。所以我不得不用這個代替,

things = [] 
for i, thing in enumerate(cmds.ls(sl=1,l=1)): 
    things.append(node()) 
    things[i].path = thing 

第一個無效的代碼很乾淨而且很短。第二個是乏味的。我如何獲得一些代碼,允許我在同一個創建行中分配一個類變量,而無需使用初始化。我避免初始化,因爲這個類將被繼承到多個文件中的許多其他類中,而且,當導入到太多的包中時,使用初始化的先前版本會變得很糟糕,從而導致未綁定的方法錯誤。

+1

簡短的答案是你不能那樣做;你不能在列表中理解任務。我可能會創建一個'node',而不是'enumerate',然後設置它的'path' *'追加'到列表中。或者,也許你可以用一個[mcve]擴展*「打破可怕」*,我們可以幫助解決這個問題,聽起來像是一個更基本的直接方法? – jonrsharpe

+0

如果setattr(n,'path',i)是我可以在cmds.ls(sl = 1,l = 1)中寫入'[n for n,i in((node(),i)無]',但我會**強烈地鼓勵你不要**。 – jonrsharpe

+0

@jonrsharpe不!用火燒吧! ;)您不僅將副作用與功能性構造混合在一起,您在您的病情中會產生副作用! –

回答

0

的原因,原來的問題都涉及到這個問題:Maya Python: Unbound Method due to Reload()。我發現的解決方案基本上是將我的跟蹤方法重新設計爲不需要初始化,然後爲了避免未綁定的錯誤,我創建了與其使用最接近的初始化序列。

trackingMethod文件:

import maya.cmds as cmds 
import maya.OpenMaya as om 

class pathTracking(object): 
    def setPathing(self, instance): 
     sel = om.MSelectionList() 
     sel.add(instance.nodeName) 
     try: 
      instance.obj = om.MObject() 
      sel.getDependNode(0, instance.obj) 
     except: 
      cmds.warning(instance.nodeName + " is somehow invalid as an openMaya obj node.") 
     try: 
      instance.dag = om.MDagPath() 
      sel.getDagPath(0,instance.dag) 
     except: 
      pass 
    def __set__(self, instance, value): 
     if isinstance(value,dict): 
      if "dag" in value: 
       instance.dag = value["dag"] 
      if "obj" in value: 
       instance.obj = value["obj"] 
      if "nodeName" in value: 
       instance.nodeName = value["nodeName"] 
       self.setPathing(instance) 
     else: 
      if isinstance(value, basestring): 
       instance.nodeName = value 
       self.setPathing(instance) 
    def __get__(self, instance, owner): 
     if instance.dag and instance.dag.fullPathName(): 
      return instance.dag.fullPathName() 
     return om.MFnDependencyNode(instance.obj).name() 

class exampleNode(object): 
    path = pathTracking() 
    dag = None 
    obj = None 
    nodeName = "" 
    someVar1 = "blah blah" 

    def initialize(self,nodeName,obj,dag): 
     if obj or dag: 
      self.obj = obj 
      self.dag = dag 
     elif nodeName: 
      self.path = nodeName 
     else: 
      return False 
     return True 

其他文件:

import trackingMethod as trm 

circleExample(trm.exampleNode): 
    def __init__(self,nodeName="",dag=None,obj=None): 
     if not self.initialize(nodeName,obj,dag) 
      self.path = cmds.circle()[0] 

,並用這種方法我可以做

circles = [circleExample(nodeName=x) for x in cmds.ls(sl=1,l=1)] 

PS。我遇到了一些需要在創建其一些位之前初始化該類的東西。下面是一個自定義詞典,它要求我在創建詞典時將自己的實例傳遞給它。在與轉換交互的每個類中重新創建這些字典結構將是單調乏味的。解決方法是將這些相關類初始化放入變換類中的函數中。這樣最終的類繼承了創建這些字典的函數,並且可以在它們的init中調用它。這樣可以避免整個俄羅斯嵌套玩偶init當您有多個文件從單個類繼承時會中斷。

雖然這個解決方案對某些人來說看起來很明顯,但我只是想拉出頭髮,想一個解決雞蛋情況的方法,需要啓動課程以獲得自我,但由於未綁定而無法啓動課堂方法錯誤。

class sqetDict(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(thing,(connection,Attribute,xform)): 
      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(thing,(connection,Attribute,xform)): 
      thing.__set__(self.instance,value) 
     else: 
      dict.__setitem__(self,key,value) 

這些類型的字典將被初始化這樣的:

def enableDicts(self): 
    self.connection = sqetDict(self, {"txyz": connection("translate"), "tx": connection("tx"), 
             "ty": connection("ty"), "tz": connection("tz"), 
             "rxyz": connection("rotate"), 
             "rx": connection("rx"), "ry": connection("ry"), "rz": connection("rz"), 
             "sxyz": connection("scale"), 
             "sx": connection("sx"), "sy": connection("sy"), "sz": connection("sz"), 
             "joxyz": connection("jointOrient"), 
             "jox": connection("jox"), "joy": connection("joy"), "joz": connection("joz"), 
             "worldMatrix": connection("worldMatrix"), 
             "worldInvMatrix": connection("worldInverseMatrix"), 
             "parentInvMatrix": connection("parentInverseMatrix")}) 
    self.value = sqetDict(self, {"txyz": Attribute("translate", "double3"), 
           "tx": Attribute("tx", "float"), "ty": Attribute("ty", "float"), 
           "tz": Attribute("tz", "float"), 
           "rxyz": Attribute("rotate", "double3"), 
           "rx": Attribute("rx", "float"), "ry": Attribute("ry", "float"), 
           "rz": Attribute("rz", "float"), 
           "sxyz": Attribute("scale", "double3"), 
           "sx": Attribute("sx", "float"), "sy": Attribute("sy", "float"), 
           "sz": Attribute("sz", "float"), 
           "joxyz": Attribute("jointOrient", "double3"), 
           "jox": Attribute("jox", "float"), "joy": Attribute("joy", "float"), 
           "joz": Attribute("joz", "float"), 
           "rotOrder": Attribute("rotateOrder", "string"), 
           "worldMatrix": Attribute("worldMatrix", "matrix"), 
           "worldInvMatrix": Attribute("worldInverseMatrix", "matrix"), 
           "parentInvMatrix": Attribute("parentInverseMatrix", "matrix"), 
           "rotatePivot": Attribute("rotatePivot", "double3"), 
           "visibility": Attribute("visibility", "long")}) 
    self.xform = sqetDict(self, {"t": xform("t"), "ro": xform("ro"), "s": xform("s")}) 

我的連接類做的cmds.connectAttr時發送的值,並將其返回像{一個字典連接的各種屬性」 in「:」in connection「,」out「:[」outConn1「,」outCon2「等等],」path「:」完整路徑名稱到屬性「}。所以你可以做些像thingA.connection [「txyz」] = thingB.connection [「txyz」] [「path」]來連接兩個對象的相對轉換。

My Attribute類允許設置和獲取屬性值,如temp = thing.value [「txyz」] temp =(value,value,value)和thing.value [「txyz」] =(0 ,0,0)將翻譯爲零。

xform做的價值的事情,但在絕對的世界空間值。

1

不僅第一個示例語法無效,您嘗試執行的操作基本上是不健全的:不會將列表推導與狀態更改(即分配給對象屬性)混合使用。無論node是什麼,似乎處理您的問題的最佳方法是添加一個參數到node.__init__,允許您在實例化node對象時設置path。然後,你可以做things = [node(x) for x in cmds.ls(sl=1, l=1)]

所以,使用單個位置參數的最基本的方法來__init__

class Node(object): 
    def __init__(self, path): 
     self.path = path 
... 

things = [Node(x) for x in cmds.ls(sl=1, l=1)] 

更重要的是,使用一個for循環是完全符合Python。試圖讓你的代碼成爲所有的單行代碼是一個根本性的錯誤。下面是我如何與你有什麼工作,已經使之更Python:

things = [] 
for path in cmds.ls(sl=1,l=1): 
    n = node() 
    n.path = path 
    things.append(n) 

以上是完全Python的,因爲它是...

+0

列表理解不會因爲資金而執行:) – LismUK