Dynamic properties
Craig Ringer
craig at postnewspapers.com.au
Fri Jan 21 10:27:28 EST 2005
On Fri, 2005-01-21 at 06:43 -0800, michael wrote:
> setattr (self, key, property (fget, fset, fdel))
> it gives me
>
> <property object at 0x4028102c>
>
> What am I doing wrong here
Properties must be defined in the class, not the instance, to work as
expected. (Edit: Nick Coghlan explained this more accurately).
You can dynamically generate properties in a metaclass or class factory,
and you can add them to a class after the class is created (even from an
instance of that class). If you add properties to an instance of a class
rather than the class its self, though, you won't get the expected
results.
.class Fred(object):
. def __init__(self):
. self._name = 'fred'
. def getname(self):
. return self._name
. def setname(self, newname):
. self._name = newname
. name = property(getname, setname)
.
.f = Fred()
.print f.name
.
.# Works:
.class Fred2(object):
. def __init__(self):
. self._name = 'fred2'
. def getname(self):
. return self._name
. def setname(self, newname):
. self._name = newname
.
.Fred2.name = property(Fred2.getname, Fred2.setname)
.f2 = Fred2()
.print f2.name
.
.# Won't work:
.class Fred3(object):
. def __init__(self):
. self._name = 'fred3'
. def getname(self):
. return self._name
. def setname(self, newname):
. self._name = newname
.
.f3 = Fred3()
.f3.name = property(f3.getname, f3.setname)
.print f3.name
.
.# Also won't work
.f3 = Fred3()
.f3.name = property(Fred3.getname, Fred3.setname)
.print f3.name
.
.# This will work, though, because while it adds the property
.# after the instance is created, it adds it to the class not
.# the instance.
.f3 = Fred3()
.Fred3.name = property(Fred3.getname, Fred3.setname)
.print f3.name
The chances are that whatever you want to do with dynamically created
properties is better done with __getattr__ and __setattr__ instead.
If they don't fit the bill, you can add properties to the class from its
instances. I intensely dislike this though, personally. I'd want to look
into using a class factory or metaclass to do the job if __getattr__ and
__setattr__ are insufficient or unacceptable.
--
Craig Ringer
More information about the Python-list
mailing list