Pythonic方式动态添加属性和setter

时间:2015-04-10 21:04:42

标签: python class properties maya

我正在为一个3D应用程序库工作,该应用程序将应用程序的功能包装到一组Python类中,并添加应用程序没有的其他功能。

我的基类中有一组属性,用于使用现有API向节点添加属性,但我想要一种更优雅的方式来动态添加属性。我目前有这个代码(在不熟悉3D应用程序的情况下可能没有多大意义),但重要的是

# Add block properties

# PROPERTIES

class Block(pyunify.Transform):
    def __init__(self, name = "Character"):
        pyunify.Transform.__init__(self, name)
        self.LockTransform()


class Spine(Block):
    def __init__(self, name = "Character", numberOfJoints=6):
        Block.__init__(self, name+"_spine")

        # Add block properties
        self.AddAttr("numberOfJoints", "long")
        self.SetAttr("numberOfJoints", numberOfJoints)

        # Create block template
        self.Template()

    # PROPERTIES
    @property
    def numberOfJoints(self):
        return self.GetAttr("numberOfJoints")

    @numberOfJoints.setter
    def numberOfJoints(self, num):
        self.SetAttr("numberOfJoints", num)

所以我可以预见其他类具有更多属性,以及我现在的方式,对于我必须在_init __

中添加它的每个属性
self.AddAttr("numberOfJoints", "long")
self.SetAttr("numberOfJoints", numberOfJoints)

然后我必须在我的类中添加2个额外的函数,一个getter和setter,用于该属性,以便我可以在我的类中调用它作为self.numberOfJoints,它将与类本身交互以及设置在3D应用程序中的伴随节点上更正属性。

    @property
    def numberOfJoints(self):
        return self.GetAttr("numberOfJoints")

    @numberOfJoints.setter
    def numberOfJoints(self, num):
        self.SetAttr("numberOfJoints", num)

与附加属性函数的唯一区别是名称,所以我想知道是否有一种方法可以在我的基类Block类中创建一个AddProperty函数,这样我就可以在我的_init__函数中执行此操作:

self.AddProperty("numberOfJoints", "long")
self.numberOfJoints = 5

除了运行<_p>的当前_init__行之外,还会动态创建getter和setter函数

self.AddAttr("numberOfJoints", "long")

任何帮助将不胜感激!

谢谢!

1 个答案:

答案 0 :(得分:5)

如果你想做一些看起来像属性访问的东西,但是在执行一个函数的情况下,你需要一个descriptor。描述符是一个看起来像属性的对象,但拦截get和set调用,并允许您运行所需的任何代码。这是一个stackoverflow问题,其中一个示例使用描述符来使用描述符更改对象的翻译:

https://stackoverflow.com/a/22292961/1936075

您可以使用相同的技巧以更易读,更少cmds的方式创建,获取和设置自定义属性。

更多代码here