Here's one way of doing what you're asking... I would suggest using __getattribute__ and __setattr__ to dispatch the methods to the custom class you invent that holds all those properties.
For example (I simplified your makeprops into __init__ just to keep the example short, but you can probably see the idea here..) class A(object): def __init__(self, **kw): class _PropHolder(object): pass for k,v in kw.items(): setattr(_PropHolder, k, property(fget=itemgetter(k))) self._custom_props = _PropHolder() def __getattribute__(self, attr): try: return getattr(self._custom_props, attr) except AttributeError: return getattr(self, attr) def __setattr__(self, attr, val): if hasattr(self._custom_props, attr): setattr(self._custom_props, attr, val) else: setattr(self, attr, val) def __delattr__(self, attr): if hasattr(self._custom_props, attr): delattr(self._custom_props, attr) else: delattr(self, attr) On 6 Feb 2008, at 12:06, [EMAIL PROTECTED] wrote: Hi all, So I understand that properties belong to a class not an instance, but nonetheless I want to add properties to an instance. I have a class which when an instance is created runs some fairly complicated code and produces a set of names which I'd like to be able to access via properties. At the moment, I'm using something like obj.getvar(name) but I'd like to be able to write obj.name. (Note that they can't be just standard attributes because they only get computed when they are accessed.) I could generate functions like obj.name() but I want it to be obj.name instead. The solution I've come up with is to create a new class for each object which is just the real class with some extra properties, and then dynamically change the class of the object to this new class. This seems to work, but I wonder if (a) there is a nicer solution than the one I'll post below, (b) if there are any dangers or pitfalls of this approach. The obvious difficulty is with derived classes. At the moment, I'm insisting that a derived class has to call a makeprops() method to create the properties. It's kind of similar to this recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/197965 but that recipe has a much simpler situation in which the properties and values are known at the time of the creation of the object (by contrast, I don't know what the properties are until the end of the __init__ method). Any thoughts? Code below to illustrate my approach. import warnings from operator import itemgetter class A(object): def __init__(self,**kwds): self._kwds = kwds self.makeprops() def __getitem__(self,i): return self._kwds[i] def makeprops(self): if not hasattr(self,'_madeprops'): self._madeprops = set() self._failedprops = set() class _A(self.__class__): pass for k,v in self._kwds.items(): if not k in self._madeprops and k in dir(self): if not k in self._failedprops: warnings.warn("Cannot create property "+k+", already used in object "+str(self),RuntimeWarning) self._failedprops.add(k) else: setattr(_A,k,property(fget=itemgetter(k))) self._madeprops.add(k) self.__class__ = _A class B(A): def __init__(self,**kwds): super(B,self).__init__(**kwds) self.makeprops() class C(A): def __init__(self,**kwds): self._kwds = kwds a = A(x=1) b = B(x=2,makeprops=3) c = C(x=3) print isinstance(a,A), isinstance(a,B), isinstance(a,C) # True False False print isinstance(b,A), isinstance(b,B), isinstance(b,C) # True True False print isinstance(c,A), isinstance(c,B), isinstance(c,C) # True False True print a.__class__ # <class '__main__._A'> print b.__class__ # <class '__main__._A'> print c.__class__ # <class '__main__.C'> print a.x # 1 print b.x # 2 print b.makeprops # <bound method _A.makeprops of <__main__._A object at 0x00A86810>> try: print c.x # raises exception except AttributeError: print "c has no element x" c.makeprops() print c.x # 3 print a.__class__ # <class '__main__._A'> print b.__class__ # <class '__main__._A'> print c.__class__ # <class '__main__._A'> --- Dan Goodman http://thesamovar.net/contact -- http://mail.python.org/mailman/listinfo/python-list
-- http://mail.python.org/mailman/listinfo/python-list