python - 初始化顺序导致类实例问题

标签 python class maya

我只是要发布到目前为止我所掌握的内容并尝试描述问题。

下面的脚本跟踪具有自定义属性的变换对象。它创建了一个接口(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 变量成为特定于实例的值,但您有问题是因为它需要由您还添加到 ClipAttribute 描述符访问,而这些描述符需要声明为类变量。

我认为解决这个问题的方法是让 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/

相关文章:

python - 使用 Factory Boy 进行 Django 测试时出错

java - 从抽象类中检索数据

c++ - 使用c++静态类成员控制所有类实例的 "mode"

qt - 在进入qt之前,maya ui是如何构建的?

python - 绘制两个变量,然后用第三个变量着色

python - 需要通过迭代excel文件来创建许多python对象

python - Python 中的跨平台音频播放

java - 将变量从 View 传递到 Activity

python - 在MAYA 2009中,是否可以捕获立方体旋转事件?

c++ - 使用 GNU C++ 为 Maya 编译时出现编译器错误