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