初始化顺序导致 class 个实例问题
Initialization order causes class instance problems
我只是想 post 我目前所拥有的并尝试描述问题。
下面的脚本跟踪具有自定义属性的转换对象。它创建了一个接口,可以轻松 __get__
和 __set__
到 Maya 节点的属性。这使得将属性值保存到场景中变得容易,以便将来可以加载场景。在脚本中,我使用 OpenMaya 来跟踪 dagObject,但简化为先尝试解决问题。如果您想使用此代码,请查看 MDagPath 和 MSelectionList。
现在..
Attributes()
需要在 __init__
之外声明才能正常工作。
Attributes()
就像现在一样,在创建时需要一个 Transform()。
如果我在 Clip()
中的 __init__
之外创建 Transform()
,生成的 Transform()
实例将引用通过此方法创建的最新 Transform()
(图片)
不能post没有声誉的图像,所以描述:
名为 _new_anim_、_new_anim_1、_new_anim_2 的三个剪辑。
当下面的脚本运行时,列表的输出都是 _new_anim_2,这是最后一个初始化的转换。
__init__
发生在 属性创建之后。
我需要将 __init__
Transform
实例传递给已初始化的属性实例。
如何?
说 clip.transform = correctTransform
似乎并不能取代对 correctTransfrom
的引用。我需要一种方法将 class 实例传递给在 __init__
.
之外初始化的 class 变量
import maya.cmds as cmds
class Attribute(object):
def __init__(self,transform,attr,*args):
self.transform = transform
self.attr = attr
self.string = "string" in args
def __set__(self, instance, value):
if self.string:
cmds.setAttr(self.transform.path()+"."+self.attr,value,dt="string")
else:
cmds.setAttr(self.transform.path()+"."+self.attr,value)
def __get__(self, instance, owner):
if self.string:
return cmds.getAttr(self.transform.path()+"."+self.attr,dt="string")
return cmds.getAttr(self.transform.path()+"."+self.attr)
class Transform(object):
def __init__(self):
self.parent = ""
self.name = ""
def setObject(self,transform):
self.parent = cmds.listRelatives(transform,p=1)[0]
self.name = cmds.ls(transform,sn=1)[0]
def path(self):
return self.parent+"|"+self.name
def getName(self):
return cmds.ls(self.path(),sn=1)[0]
def rename(self,value):
self.name = cmds.ls(cmds.rename(self.path(),value),sn=1)[0]
class Clip(object):
transform = Transform()
start = Attribute(transform,"STA")
end = Attribute(transform,"END")
loop = Attribute(transform,"Loop")
relative = Attribute(transform,"RelativeToStart")
speedState = Attribute(transform,"SpeedState")
speed = Attribute(transform,"SpeedVal")
def __init__(self,transform):
self.transform.setObject(transform)
如果我没有正确理解您的问题,您似乎希望 Clip
class 中的 transform
变量成为特定于实例的值,但您有问题,因为它需要被您也添加到 Clip
的 Attribute
描述符访问,需要声明为 class 变量。
我认为解决这个问题的方法是让 Attribute
class 的 __get__
和 __set__
方法在 instance
它们是传入的,而不是 self
.
试试这个:
class Attribute(object):
def __init__(self,attr,*args): # no transform parameter or instance variable
self.attr = attr
self.string = "string" in args
def __set__(self, instance, value): # look up transform on instance, rather than self
if self.string:
cmds.setAttr(instance.transform.path()+"."+self.attr,value,dt="string")
else:
cmds.setAttr(instance.transform.path()+"."+self.attr,value)
def __get__(self, instance, owner): # here too
if self.string:
return cmds.getAttr(instance.transform.path()+"."+self.attr,dt="string")
return cmds.getAttr(instance.transform.path()+"."+self.attr)
# Transform can stay the same, though you could merge set_object into __init__
class Clip(object):
# no more transform class variable
start = Attribute("STA") # no more transform argument passed to the Attributes
end = Attribute("END")
loop = Attribute("Loop")
relative = Attribute("RelativeToStart")
speedState = Attribute("SpeedState")
speed = Attribute("SpeedVal")
def __init__(self,transform):
self.transform = Transform() # create transform as an instance variable
self.transform.setObject(transform)
我只是想 post 我目前所拥有的并尝试描述问题。
下面的脚本跟踪具有自定义属性的转换对象。它创建了一个接口,可以轻松 __get__
和 __set__
到 Maya 节点的属性。这使得将属性值保存到场景中变得容易,以便将来可以加载场景。在脚本中,我使用 OpenMaya 来跟踪 dagObject,但简化为先尝试解决问题。如果您想使用此代码,请查看 MDagPath 和 MSelectionList。
现在..
Attributes()
需要在 __init__
之外声明才能正常工作。
Attributes()
就像现在一样,在创建时需要一个 Transform()。
如果我在 Clip()
中的 __init__
之外创建 Transform()
,生成的 Transform()
实例将引用通过此方法创建的最新 Transform()
(图片)
不能post没有声誉的图像,所以描述: 名为 _new_anim_、_new_anim_1、_new_anim_2 的三个剪辑。 当下面的脚本运行时,列表的输出都是 _new_anim_2,这是最后一个初始化的转换。
__init__
发生在 属性创建之后。
我需要将 __init__
Transform
实例传递给已初始化的属性实例。
如何?
说 clip.transform = correctTransform
似乎并不能取代对 correctTransfrom
的引用。我需要一种方法将 class 实例传递给在 __init__
.
import maya.cmds as cmds
class Attribute(object):
def __init__(self,transform,attr,*args):
self.transform = transform
self.attr = attr
self.string = "string" in args
def __set__(self, instance, value):
if self.string:
cmds.setAttr(self.transform.path()+"."+self.attr,value,dt="string")
else:
cmds.setAttr(self.transform.path()+"."+self.attr,value)
def __get__(self, instance, owner):
if self.string:
return cmds.getAttr(self.transform.path()+"."+self.attr,dt="string")
return cmds.getAttr(self.transform.path()+"."+self.attr)
class Transform(object):
def __init__(self):
self.parent = ""
self.name = ""
def setObject(self,transform):
self.parent = cmds.listRelatives(transform,p=1)[0]
self.name = cmds.ls(transform,sn=1)[0]
def path(self):
return self.parent+"|"+self.name
def getName(self):
return cmds.ls(self.path(),sn=1)[0]
def rename(self,value):
self.name = cmds.ls(cmds.rename(self.path(),value),sn=1)[0]
class Clip(object):
transform = Transform()
start = Attribute(transform,"STA")
end = Attribute(transform,"END")
loop = Attribute(transform,"Loop")
relative = Attribute(transform,"RelativeToStart")
speedState = Attribute(transform,"SpeedState")
speed = Attribute(transform,"SpeedVal")
def __init__(self,transform):
self.transform.setObject(transform)
如果我没有正确理解您的问题,您似乎希望 Clip
class 中的 transform
变量成为特定于实例的值,但您有问题,因为它需要被您也添加到 Clip
的 Attribute
描述符访问,需要声明为 class 变量。
我认为解决这个问题的方法是让 Attribute
class 的 __get__
和 __set__
方法在 instance
它们是传入的,而不是 self
.
试试这个:
class Attribute(object):
def __init__(self,attr,*args): # no transform parameter or instance variable
self.attr = attr
self.string = "string" in args
def __set__(self, instance, value): # look up transform on instance, rather than self
if self.string:
cmds.setAttr(instance.transform.path()+"."+self.attr,value,dt="string")
else:
cmds.setAttr(instance.transform.path()+"."+self.attr,value)
def __get__(self, instance, owner): # here too
if self.string:
return cmds.getAttr(instance.transform.path()+"."+self.attr,dt="string")
return cmds.getAttr(instance.transform.path()+"."+self.attr)
# Transform can stay the same, though you could merge set_object into __init__
class Clip(object):
# no more transform class variable
start = Attribute("STA") # no more transform argument passed to the Attributes
end = Attribute("END")
loop = Attribute("Loop")
relative = Attribute("RelativeToStart")
speedState = Attribute("SpeedState")
speed = Attribute("SpeedVal")
def __init__(self,transform):
self.transform = Transform() # create transform as an instance variable
self.transform.setObject(transform)