Adding properties to objects
Peter Otten
__peter__ at web.de
Tue Apr 13 14:37:37 EDT 2004
Matthew Barnes wrote:
> Is it possible to add properties to objects dynamically?
>
> I have an instance (x) of some new-style class (Foo), and I would like
> to be able to do something like:
>
>>>> x = Foo()
>>>> x.myproperty = property(getsomething, setsomething, delsomething);
>>>> x.myproperty # invokes getsomething
>>>> x.myproperty = 1 # invokes setsomething
>>>> del x.myproperty # invokes delsomething
>
> However, when I evaluate x.myproperty I get back a property object
> (which makes sense). I get the feeling I'm missing a step to "bind"
> the property object to the class instance.
>
> Is this possible (it's Python... of course it's possible, right?), and
> if so, how?
Fresh from the mad coders' department, here's how to dynamically change an
object's class to get the desired effect:
import new
class Foo(object):
def __setattr__(self, name, value):
if isinstance(value, property):
klass = new.classobj(self.__class__.__name__, (self.__class__,),
{})
setattr(klass, name, value)
self.__class__ = klass
else:
object.__setattr__(self, name, value)
f1 = Foo()
f1.name = "first"
def set1(self, v):
self.name = v[1:-1]
def get1(self):
return "(%s)" % self.name
f1.prp = property(get1, set1)
f2 = Foo()
f2.name = "second"
def set2(self, v):
self.name = v[2:-2]
def get2(self):
return "<<%s>>" % self.name
f2.prp = property(get2, set2)
print f1.prp, f2.prp
f2.prp = "((was second))"
print f1.prp, f2.prp
f2.__class__.prp = f1.__class__.prp
print f1.prp, f2.prp
If you try the above approach, you will of course end up with more classes
than instances - if you only expect a limited number of dynamic properties
you could put all combinations into a class cache.
:-)
Peter
More information about the Python-list
mailing list