Maya Python 单行 class 实例和 class 变量赋值?
Maya Python single line class instance and class variable assignment?
我想做这样的事情,
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
第一个无效代码简洁明了。第二个很乏味。我怎样才能获得一些代码,使我可以在不使用初始化的情况下在同一创建行中分配一个 class 变量。我正在避免初始化,因为这个 class 将被跨多个文件继承到许多其他 classes 中,而我以前使用初始化的版本在导入太多包时会崩溃,导致未绑定的方法错误.
不仅第一个示例语法无效,而且您尝试做的事情从根本上讲是不合理的:不要将列表推导与状态更改(即分配给对象属性)混合使用。 无论 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 循环是 完美的 Pythonic。试图让你的代码全部是一行代码是一种根本性的误导。以下是我将如何使用你已有的东西并使它更像 Pythonic:
things = []
for path in cmds.ls(sl=1,l=1):
n = node()
n.path = path
things.append(n)
上面的内容完全是 Pythonic 的……
原题的原因与这个问题有关:Maya Python: Unbound Method due to Reload()。我找到的解决方案基本上是修改我的跟踪方法,使其不需要初始化,然后,为了避免未绑定错误,我创建了最接近其使用的初始化序列。
跟踪方法文件:
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。我 运行 进入一些需要 class 初始化的东西,然后才能创建它的一些位。下面是一个自定义字典,它要求我在创建字典时将一个 self 实例传递给它。在每个与 t运行sform 交互的 class 中重新创建这些 dict 结构将是乏味的。解决方案是将这些依赖 class 初始化放入 t运行sform class 中的函数中。这样最终的 class 继承了创建字典的函数并且可以在它们的 init 中调用它。这避免了 init 语句的整个俄罗斯嵌套娃娃在您有多个文件继承自单个 class 时中断。
虽然这个解决方案对某些人来说似乎很明显,但我只是想出一个解决鸡蛋问题的方法,需要初始化 class 来获取自我,但无法由于未绑定方法错误,init class。
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")})
我的连接 class 在发送一个值时执行 cmds.connectAttr,它 returns 连接的各种属性作为字典,如 {"in": "in connection", "out":["outConn1","outCon2", 等等], "path":"fullpath name to attribute"}。所以你可以做类似的事情,thingA.connection["txyz"] = thingB.connection["txyz"]["path"] 来连接相对的 t运行slates两个对象。
我的属性 class 允许设置和获取属性值,例如 temp = thing.value["txyz"] 结果为 temp = (value,value,value),并且 thing.value["txyz"]=(0,0,0) 会将 t运行slate 归零。
xform 做值的事情,但在绝对世界中 space 值。
我想做这样的事情,
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
第一个无效代码简洁明了。第二个很乏味。我怎样才能获得一些代码,使我可以在不使用初始化的情况下在同一创建行中分配一个 class 变量。我正在避免初始化,因为这个 class 将被跨多个文件继承到许多其他 classes 中,而我以前使用初始化的版本在导入太多包时会崩溃,导致未绑定的方法错误.
不仅第一个示例语法无效,而且您尝试做的事情从根本上讲是不合理的:不要将列表推导与状态更改(即分配给对象属性)混合使用。 无论 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 循环是 完美的 Pythonic。试图让你的代码全部是一行代码是一种根本性的误导。以下是我将如何使用你已有的东西并使它更像 Pythonic:
things = []
for path in cmds.ls(sl=1,l=1):
n = node()
n.path = path
things.append(n)
上面的内容完全是 Pythonic 的……
原题的原因与这个问题有关:Maya Python: Unbound Method due to Reload()。我找到的解决方案基本上是修改我的跟踪方法,使其不需要初始化,然后,为了避免未绑定错误,我创建了最接近其使用的初始化序列。
跟踪方法文件:
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。我 运行 进入一些需要 class 初始化的东西,然后才能创建它的一些位。下面是一个自定义字典,它要求我在创建字典时将一个 self 实例传递给它。在每个与 t运行sform 交互的 class 中重新创建这些 dict 结构将是乏味的。解决方案是将这些依赖 class 初始化放入 t运行sform class 中的函数中。这样最终的 class 继承了创建字典的函数并且可以在它们的 init 中调用它。这避免了 init 语句的整个俄罗斯嵌套娃娃在您有多个文件继承自单个 class 时中断。
虽然这个解决方案对某些人来说似乎很明显,但我只是想出一个解决鸡蛋问题的方法,需要初始化 class 来获取自我,但无法由于未绑定方法错误,init class。
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")})
我的连接 class 在发送一个值时执行 cmds.connectAttr,它 returns 连接的各种属性作为字典,如 {"in": "in connection", "out":["outConn1","outCon2", 等等], "path":"fullpath name to attribute"}。所以你可以做类似的事情,thingA.connection["txyz"] = thingB.connection["txyz"]["path"] 来连接相对的 t运行slates两个对象。
我的属性 class 允许设置和获取属性值,例如 temp = thing.value["txyz"] 结果为 temp = (value,value,value),并且 thing.value["txyz"]=(0,0,0) 会将 t运行slate 归零。
xform 做值的事情,但在绝对世界中 space 值。