2

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 ?

MObject
  • 397
  • 3
  • 14

2 Answers2

4

You don't need a metaclass here. You can do something like this:

def make_xsi_property(name):
    def get_prop(self):
        return xsi.getValue('{}.{}'.format(self.object, name))
    def set_prop(self, value):
        tx = xsi.setValue('{}.{}'.format(self.object, name), value)
    return property(get_prop, set_prop)

class MyClass(object):
    tx = make_xsi_property('kine.local.posx')
    ty = make_xsi_property('kine.local.posy')
    #...
Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
interjay
  • 107,303
  • 21
  • 270
  • 254
  • Working solution too, but wrt/ custom descriptor it means one more attribute lookup and function call (none of them being cheap in Python) for each attribute access, and the custom descriptor is not much longer nor complicated. – bruno desthuilliers Jul 07 '12 at 19:55
  • @brunodesthuilliers: Simplicity of code should take precedence over micro-optimizations like this unless you verify that this is a performance bottleneck. And if the cost of a function call is that important to you then perhaps Python isn't the language you should be programming in. – interjay Jul 08 '12 at 08:40
  • using a proper descriptor when that's what you need is none more complex than writing a closure that generates a generic descriptor, and avoiding useless attribute lookups and function calls is definitly not "micro optimization", just sane programming practice, whatever the language. FWIW I've been using Python for about 12 years now... – bruno desthuilliers Jul 08 '12 at 09:50
3

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
Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118