Edit: My previous answer tried to create a generic metaclass "AutoProperties", which I hope can be useful. As @martineau's answer shows, a solution specializing in the Vector class can simplify the task.
Here is another idea on these lines (specialized simplicity over generalized complexity). It uses a class decorator (which, I think, is a little easier to understand than a metaclass) and the idea of ββ@martineau to simplify getters and setters with default values:
def AutoProperties(*props): def _AutoProperties(cls): for attr in props: def getter(self,_attr='_'+attr): return getattr(self, _attr) def setter(self, value, _attr='_'+attr): setattr(self, _attr, float(value)) setattr(cls,attr,property(getter,setter)) return cls return _AutoProperties @AutoProperties('x','y','z') class Vector(object): '''Creates a Maya vector/triple, having x, y and z coordinates as float values''' def __init__(self, x=0, y=0, z=0): self._x, self._y, self._z = map(float,(x, y, z))
Original answer: Here you can avoid repeating the boiler plate code when defining many similar properties.
I tried to make the solution quite general, so it can be useful to people in other situations next to this specific one.
To use it, you need to do 2 things:
- Placed
__metaclass__=AutoProperties(('x','y','z'))
at the beginning of your class definition. You can list (as strings) as many attributes (e.g. x , y , z ) as you wish. AutoProperties will turn them into properties.
- Your class, for example.
Vector , you need to define staticmethods _auto_setter and _auto_getter . They take one argument, the attribute name as a string, and return the setter or getter function, respectively, for that attribute.
The idea of ββusing metaclasses to automatically set properties comes from Guido Rossum's essay on properties and metaclasses . There, it defines an autoprop , similar to what I use below. The main difference is that AutoProperties expects the user to define recipient factories and setters instead of manual determinants and setters.
def AutoProperties(props): class _AutoProperties(type): # Inspired by autoprop (http://www.python.org/download/releases/2.2.3/descrintro/) def __init__(cls, name, bases, cdict): super(_AutoProperties, cls).__init__(name, bases, cdict) for attr in props: fget=cls._auto_getter(attr) fset=cls._auto_setter(attr) setattr(cls,attr,property(fget,fset)) return _AutoProperties class Vector(object): '''Creates a Maya vector/triple, having x, y and z coordinates as float values''' __metaclass__=AutoProperties(('x','y','z')) def __init__(self, x=0, y=0, z=0): # I assume you want the initial values to be converted to floats too. self._x, self._y, self._z = map(float,(x, y, z)) @staticmethod def _auto_setter(attr): def set_float(self, value): setattr(self, '_'+attr, float(value)) return set_float @staticmethod def _auto_getter(attr): def get_float(self): return getattr(self, '_'+attr) return get_float if __name__=='__main__': v=Vector(1,2,3) print(vx) # 1.0 vx=4 print(vx) # 4.0