Search code examples
pythonclassmetaclassxsi

About metaclass in Python


I try to make a class in python (with XSI / Softimage) to override default methods.

class transform(object):
    def __init__ (self) :
        self.object = self._build()
        self.type = ''
    def _build (self):
        object = None
        return object
    @property
    def name(self):
        name = xsi.getValue(str(self.object) + '.Name')
        return str(name)    
    @name.setter
    def name(self, value):
        name = xsi.setValue(str(self.object) + '.Name', value)
        self.object = str(name)
    ################## TRANSLATE ######################
    @property
    def tx(self):
        tx = xsi.getValue(str(self.object) + '.kine.local.posx')
        return tx
    @tx.setter
    def tx(self, value):
        tx = xsi.setValue(str(self.object) + '.kine.local.posx', value)
    @property
    def ty(self):
        ty = xsi.getValue(str(self.object) + '.kine.local.posy')
        return ty
    @ty.setter
    def ty(self, value):
        ty = xsi.setValue(str(self.object) + '.kine.local.posy', value)
    @property
    def tz(self):
        tz = xsi.getValue(str(self.object) + '.kine.local.posz')
        return tz
    @tz.setter
    def tz(self, value):
        tz = xsi.setValue(str(self.object) + '.kine.local.posz', value) 

But as you can see i duplicate a lot. How can i simplify this ? Maybe with metaclass ?


Solution

  • the property type is just one (handy) shortcut for descriptors. For your case, the simplest solution is a custom descriptor, ie:

    class XsiDescriptor(object):
        def __init__(self, xsi):
            self.xsi = xsi
    
        def __get__(self, instance, cls=None):
            if instance is None:
                return self
            key = "%s.%s" % (instance.object, self.xsi)
            return xsi.getValue(key)
    
        def __set__(self, instance, value):
            key = "%s.%s" % (instance.object, self.xsi)
            xsi.setValue(key, value)
    
    
      class Transform(object):
          # your init etc here
    
          tx = XsiDescriptor("kine.local.posx")
          ty = XsiDescriptor("kine.local.posy")
    
          # etc