我只是要发布到目前为止我所掌握的内容并尝试描述问题。
下面的脚本跟踪具有自定义属性的变换对象。它创建了一个接口(interface),可以轻松地对 Maya 节点的属性进行 __get__
和 __set__
操作。这样可以轻松地将属性值保存到场景中,以便将来随场景一起加载。在脚本中,我使用 OpenMaya 来跟踪 dagObject,但进行了简化以尝试首先解决问题。如果您想使用此代码,请查看 MDagPath 和 MSelectionList。
现在..
Attributes()
需要在 __init__
之外声明才能正常工作。
现在的 Attributes() 需要在创建时使用 Transform() 。
如果我在 Clip()
中的 __init__
之外创建 Transform()
,则生成的 Transform()
实例将引用此方法创建的最新 Transform()
(图像)
无法发布没有声誉的图片,因此描述性如下: 名为 _new_anim_、_new_anim_1、_new_anim_2 的三个剪辑。 当下面的脚本运行时,列表的输出都是 _new_anim_2,这是初始化的最后一个变换。
__init__
发生在创建属性之后。
我需要将 __init__
Transform
实例传递给已初始化的属性实例。
如何?
说clip.transform = CorrectTransform
似乎并不能取代对 CorrectTransfrom
的引用。我需要一种方法将类实例传递给在 __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
类中的 transform
变量成为特定于实例的值,但您有问题是因为它需要由您还添加到 Clip
的 Attribute
描述符访问,而这些描述符需要声明为类变量。
我认为解决这个问题的方法是让 Attribute
类的 __get__
和 __set__
方法查找 transform
在它们传入的实例
上,而不是在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)
关于python - 初始化顺序导致类实例问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32479113/