[Zope-CMF] Add attributes to class which already has instances in ZODB
Jeffrey P Shell
jeffrey@cuemedia.com
Thu, 9 Jan 2003 11:49:13 -0700
If you're writing the class in Python, you can add a __setstate__
method to the class. This is called when the ZODB loads an instance of
your class into memory. A ZopeLabs Cookbook recipe has some details
and an example:
http://www.zopelabs.com/cookbook/1002251996
Some Python documentation can be found in the current Python docs:
http://www.python.org/doc/lib/pickle-inst.html
So if you have all of your instance attributes usually set up during
__init__, and you add to that list later, you want to use __setstate__.
class Foo(Persistent):
def __setstate__(self, v):
Foo.inheritedAttribute('__setstate__')(self, v)
if not hasattr(self, 'email'):
self.email = "" # or some default value
Another way is to put the attribute definitions inside the class block
itself. Due to Python's laws of mutability, you have to be careful
what you put in here. But putting an attribute in a class statement
would cause all objects to pick up that attribute (they're really
"Shared Instance" attributes).
class Foo(Persistent):
email = ""
Of course, a better design would be to implement everything with
getter/setter methods (or at least getters). It makes changes to the
class easier.
class Foo(Persistent):
_email = ""
def email(self):
return self._email
def set_email(self, email):
self._email = email
This design pattern is best for Zope because you can keep the actual
attribute hidden from Python Scripts, etc (they can't access names with
underscores), and place different permissions on the 'email' and
'set_email' methods. You can also avoid acquisition surprises, since
you can't acquire names beginning with an underscore.
Another way that 'def email' can be written in this situation is:
def email(self):
if hasattr(self, '_email'):
return self._email
else:
return ""
(or more succinctly):
def email(self):
return getattr(self, '_email', "")
This is the easiest way to add new attribute-like values to objects,
since the new methods will be usable by all existing instances, and you
can add code into the methods themselves to deal with instances that
don't have a certain attribute set.
--
Jeffrey P Shell
On Thursday, January 9, 2003, at 03:12 AM, Rainer Thaden wrote:
> Hi,
>
> let's say you've written a type-class for CMF with some attributes,
> but you are not sure, if there are attributes missing. When you notice
> that there are missing attributes it will be too late to change the
> class, because there are already some instances in the ZODB, which you
> can't assign the new attributes.
> What would you do to prevent this situation when developing the class?
> Is it possible to add some dummy attributes and assign them the
> appropriate name afterwards like
>
> Attribute list:
> name='' #'normal' attributes
> birth=''
> ext1='' #dummy attributes
> ext2=''
>
> and then you notice that you need an attribute for an email and
> write
>
> email=ext1
>
> inside the class.
>
> Will a call to email on the objects which are already in the ZODB
> resolve the right name?
>
> --
> Regards,
> Rainer mailto:thadi@gmx.de
>
>
> _______________________________________________
> Zope-CMF maillist - Zope-CMF@zope.org
> http://lists.zope.org/mailman/listinfo/zope-cmf
>
> See http://collector.zope.org/CMF for bug reports and feature requests